React TypeScript:路线位置和子代属性的正确类型

时间:2019-11-23 07:27:34

标签: reactjs typescript react-router-v4

我有一个传递位置道具和儿童道具的路由器,但我不知道这些道具的正确类型。

这是使用react-router-dom的路由器...

import React, { useReducer } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { globalContext, setGlobalContext } from './components/context';
import { Layout } from './components/layout';
import { defaultState, globalReducer } from './components/reducer';
import { Home } from './routes/home';
import { NotFound } from './routes/notFound';

const Router: React.FC = () => {
  const [global, setGlobal] = useReducer(globalReducer, defaultState);
  return (
    <setGlobalContext.Provider value={{ setGlobal }}>
      <globalContext.Provider value={{ global }}>
        <BrowserRouter>
          <Route
            render={({ location }) => (
              <Layout location={location}>
                <Switch location={location}>
                  <Route exact path='/' component={Home} />
                  <Route component={NotFound} />
                </Switch>
              </Layout>
            )}
          />
        </BrowserRouter>
      </globalContext.Provider>
    </setGlobalContext.Provider>
  );
};

export { Router };

在内部布局组件中,我有一个用于位置和子项的接口,但是由于我不知道这些类型的正确类型,因此最终使用了其中的任何一个,因此我的短绒棉就适合了。

import React from 'react';

interface PropsInterface {
  children: any;
  location: any;
}

const Layout: React.FC<PropsInterface> = (props: PropsInterface) => {
  return (
    <div>
      <p>{props.location}</p>
      <p>{props.children}</p>
    </div>
  );
};

export { Layout };

我得到的错误是'any'的类型声明丢失了类型安全性。考虑用更精确的类型替换它。 (无)tslint(1)

我可以从导入import { useLocation } from 'react-router-dom';中获取位置

2 个答案:

答案 0 :(得分:2)

您要查找的Route的界面可以在@types/react-router定义中找到。

在您的项目中安装该代码之后,您应该可以使用如下所示的界面使该TS错误静音:

// Layout.tsx

import { RouteProps } from "react-router";

interface ILayoutProps {
  location: RouteProps["location"];
  children: RouteProps["children"];
}

const Layout: React.FC<ILayoutProps> = (props: ILayoutProps) => {
  return <div>{props.children}</div>;
};

请记住,location是一个对象,因此React不会让您像以前那样渲染它。

以下是工作示例的链接:https://codesandbox.io/s/zealous-snyder-yw9dg


另一种选择是使用Partial界面,但这将使所有ILayoutProps是可选的:

interface ILayoutProps extends Partial<RouteProps> {}

答案 1 :(得分:0)

您还可以使用 RouteComponentProps 公开的 react-router-dom 找到这些类型的接口。试试:

import { RouteComponentProps } from "react-router-dom";

并将其映射到您的组件,如下所示:

// Layout.tsx

import { RouteComponentProps } from "react-router-dom";

const Layout: React.FC<RouteComponentProps> = (props) => {
  return <div>{props.children}</div>;
};