简体   繁体   English

TypeScript 中基于配置的 React Router 抛出 eslint 错误

[英]Configuration based React Router in TypeScript throwing eslint errors

Okay, as I look through the docs for React Router, I see that the suggestion is to use the new routers that support the standard Data History Web APIs , which are relatively new.好的,当我浏览 React Router 的文档时, 我看到建议是使用支持标准数据历史记录 Web API的新路由器,这些 API 相对较新。

I'm in a browser, so I'm going to use createBrowserRouter .我在浏览器中,所以我将使用createBrowserRouter

There's some sample code there in JavaScript. I need to port this to TypeScript for my project. JavaScript 中有一些示例代码。我需要将其移植到 TypeScript 以用于我的项目。

import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";

import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    loader: rootLoader,
    children: [
      {
        path: "team",
        element: <Team />,
        loader: teamLoader,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

When I do, I have errors.当我这样做时,我有错误。

I tried removing most of the stuff I don't think I need, like the loaders, etc.我尝试删除大部分我认为不需要的东西,比如装载机等。

Here's my first cut:这是我的第一个剪辑:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import type { BrowserRouter } from 'react-router-dom';
import AnItem from './components/Shared/AnItem';

const myRouter: BrowserRouter = createBrowserRouter([
    {
        path: '/',
        element: <AnItem />,
    },
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
        <RouterProvider router={myRouter} />
    </React.StrictMode>
);

There, I get a number of issues about any values, starting with the following line:在那里,我得到了许多关于any值的问题,从以下行开始:

const myRouter: BrowserRouter = createBrowserRouter([

There are three errors reported just for that line (I'll include them all in a screenshot, below):仅针对该行报告了三个错误(我将在下面的屏幕截图中全部包含它们):

  • Unsafe assignment of an any value. any值的不安全赋值。
  • 'BrowserRouter' refers to a value, but is being used as a type here. “BrowserRouter”指的是一个值,但在这里用作类型。 Did you mean 'typeof BrowserRouter'?您指的是 'typeof BrowserRouter' 吗?
  • Unsafe call of an any typed value. any类型值的不安全调用。

VS Code 中显示的错误

What's wrong there?那里出了什么问题? I've typed myRouter .我输入myRouter I get that the array is untyped for createBrowserRouter , but I thought it could infer.我知道数组对于createBrowserRouter是无类型的,但我认为它可以推断。

But let's pull it out and strongly type that array.但是让我们把它拉出来并强类型化那个数组。

import React from 'react';
import ReactDOM from 'react-dom/client';
import type { RouteObject } from 'react-router';
import type { BrowserRouter } from 'react-router-dom';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import AnItem from './components/Shared/AnItem';

const routes: RouteObject[] = [
    {
        path: '/',
        element: <AnItem />,
    },
];

const myRouter: BrowserRouter = createBrowserRouter(routes);

ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
        <RouterProvider router={myRouter} />
    </React.StrictMode>
);

Now it's happy through routes but still yells at me for...现在它很高兴通过routes ,但仍然对我大喊大叫......

const myRouter: BrowserRouter = createBrowserRouter(routes);

Unsafe assignment of an any value. any值的不安全赋值。

VS Code 弹出窗口解释了任何值的不安全赋值。

Where is the any ? any在哪里? Is it from createBrowserRouter somehow?它是以某种方式来自createBrowserRouter的吗? If I mouseover in VS Code, I get "intellisense" (if that's still what it's called), so I think my types, etc, are all mapping correctly:如果我将鼠标悬停在 VS Code 中,我会得到“intellisense”(如果这仍然是它的名称),所以我认为我的类型等都正确映射:

(alias) createBrowserRouter(routes: RouteObject[], opts?: {
    basename?: string | undefined;
    hydrationData?: Partial<Pick<RouterState, "loaderData" | "actionData" | "errors">> | undefined;
    window?: Window | undefined;
} | undefined): Router
import createBrowserRouter

That says pretty clearly it returns a Router .这很清楚地说明它返回一个Router

It looks like it can't figure out what BrowserRouter is from that type BrowserRouter = /*unresolved*/ any .看起来它无法从type BrowserRouter = /*unresolved*/ any中找出BrowserRouter是什么。 But when I mouseover the import, I get:但是当我将鼠标悬停在导入上时,我得到:

(alias) function BrowserRouter({ basename, children, window, }: BrowserRouterProps): JSX.Element
import BrowserRouter
A <Router> for use in web browsers. Provides the cleanest URLs.

'BrowserRouter' is declared but its value is never read.ts(6133)

So that seems in context too, though the "its value is never read" is surprising.所以这在上下文中似乎也是如此,尽管“它的价值永远不会被读取”是令人惊讶的。

Now I did try to type myRouter as a Router , but I get yelled at that I should use a more specific type of router:现在我确实尝试将myRouter键入为Router ,但有人大喊我应该使用更具体类型的路由器:

Note: You usually won't render a directly [sic].注意:您通常不会直接渲染 [sic]。 Instead, you'll render a router that is more specific to your environment such as a in web browsers or a for server rendering.相反,您将渲染一个更特定于您的环境的路由器,例如 web 浏览器或用于服务器渲染的路由器。

So I'm using BrowserRouter .所以我正在使用BrowserRouter But its error is:但它的错误是:

'BrowserRouter' refers to a value, but is being used as a type here. “BrowserRouter”指的是一个值,但在这里用作类型。 Did you mean 'typeof BrowserRouter'?您指的是 'typeof BrowserRouter' 吗?

I'm pretty sure I don't mean typeof ;我很确定我不是指typeof I'm defining a variable as a specifc type.我将变量定义为特定类型。

What am I missing here?我在这里错过了什么? I'm having a hard time googling up an example that both uses configuration instead of components for routing (and I think configuration is what I want as the new Data History API routers require it) and is in TypeScript.我很难用谷歌搜索一个例子,它都使用配置而不是组件进行路由(我认为配置是我想要的,因为新的数据历史 API 路由器需要它)并且在 TypeScript 中。

Looks like Drew's on to something.看起来德鲁在做某事。 Here are my dependencies from package.json:这是我来自 package.json 的依赖项:

    "dependencies": {
        "bootstrap": "^5.2.3",
        "react": "^18.2.0",
        "react-bootstrap": "^2.7.0",
        "react-dom": "^18.2.0",
        "react-router": "^6.7.0",
        "react-router-dom": "^6.7.0"
    },
    "devDependencies": {
        "@types/react": "^18.0.26",
        "@types/react-dom": "^18.0.9",
        "@typescript-eslint/eslint-plugin": "^5.48.2",
        "@typescript-eslint/parser": "^5.48.2",
        "@vitejs/plugin-react-swc": "^3.0.0",
        "eslint": "^8.32.0",
        "eslint-config-prettier": "^8.6.0",
        "eslint-config-xo": "^0.43.1",
        "eslint-config-xo-typescript": "^0.55.1",
        "eslint-plugin-react": "^7.32.1",
        "opener": "^1.5.2",
        "typescript": "^4.9.4",
        "vite": "^4.0.0"
    }

Update: If I disable those rules and take out the typing, things do render as I'd expect.更新:如果我禁用这些规则并取消输入,事情就会按照我的预期呈现。

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
//...
const routes: RouteObject[] = [
    {
        path: '/',
        element: (
            <div>
                <a href="./test">test</a>
            </div>
        ),
    },
    { path: '/test', element: <div>hello</div> },
];

// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const myRouter = createBrowserRouter(routes);

ReactDOM.createRoot(document.getElementById('root')!).render(
    <React.StrictMode>
        <RouterProvider router={myRouter} />
    </React.StrictMode>
);

react-router@6 and react-router-dom@6 are completely written in Typescript, so there is no need to import external typings. react-router@6react-router-dom@6完全写在 Typescript 中,所以不需要导入外部类型。 The v5 typings are likely messing with your build step. v5 类型可能会干扰您的构建步骤。

You should uninstall @types/react-router and @types/react-router-dom .您应该卸载@types/react-router@types/react-router-dom

npm uninstall --save @types/react-router
npm uninstall --save @types/react-router-dom

From here I don't believe you'll need to explicitly type the data router.从这里我认为您不需要明确键入数据路由器。 The return type from createBrowserRouter is RemixRouter , not BrowserRouter . RemixRouter createBrowserRouter而不是BrowserRouter

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import AnItem from './components/Shared/AnItem';

const myRouter = createBrowserRouter([
  {
    path: '/',
    element: <AnItem />,
  },
]);

ReactDOM.createRoot(document.getElementById('root')!)
  .render(
    <React.StrictMode>
      <RouterProvider router={myRouter} />
    </React.StrictMode>
  );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM