如何将 React 路由器功能转换为 Typescript?

Posted

技术标签:

【中文标题】如何将 React 路由器功能转换为 Typescript?【英文标题】:How To Translate React Router Function to Typescript? 【发布时间】:2021-01-31 00:31:06 【问题描述】:

我开始在 React 项目上工作,使用 react-router-dom 并且客户端需要将项目代码转换为 Typescript

我建立2个文件夹“RouteWrapper.js”和“ProviderRoutes.js”

1-“RouteWrapper.js”

import React from 'react';
import PropTypes from 'prop-types';
import  Route, Redirect  from 'react-router-dom';

export default function RouteWrapper(
  component: Component,
  isPrivate,
  ...rest
) 
  const signed = false;

  if (!signed && isPrivate) 
    return <Redirect exact to="/signin" />;
  

  if (signed && !isPrivate) 
    return <Redirect to="/" />;
  

  return (
    <Route ...rest component=Component />
  );


RouteWrapper.propTypes = 
  isPrivate: PropTypes.bool,
  component: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
    .isRequired,
;

RouteWrapper.defaultProps = 
  isPrivate: false,
;

2-“ProviderRoutes.js”

import React from 'react';
import  Switch  from 'react-router-dom';

// Components
import Route from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes() 
  return (
    <Switch>
        <Route exact path=["/signin", "/signup", "/reset-password"] component=Authentication />
        <Route path="/" component=ChatApplication isPrivate />
    </Switch>
  )

【问题讨论】:

Typescript 是 javascript 的超集。所以这已经是打字稿了。您面临的问题是什么? 在第一个文件第 6 行和第 7 行“绑定元素‘组件’隐含地具有‘任何’类型。”和“绑定元素 'isPrivate' 隐含地具有 'any' 类型。” 你是要问我们如何为这段代码的每一行添加类型? 是的,对不起,我对这个问题感到困惑 这对于***来说太宽泛了(我们可以在上面写一个博客系列) 【参考方案1】:

我相信问题主要出在RouteWrapper。首先,假设您不再想使用 prop 类型,因为现在 TypeScript 在编译时检查类型。

这些是基础:

React 使用module.exports = React 导出。这意味着技术上正确的导入方式 反应是import * as React from 'react';。或者,您可以将"esModuleInterop": true 设置为 tsconfig.json。 React 组件的返回类型为React.ReactElement

也可以使用解构在功能组件中分配简单的默认道具。

对于&lt;RouteWrapper /&gt;具体component是从props中提取出来的,然后传递给 &lt;Route /&gt; 以及其他道具。这意味着它也可以包含在其余的道具中。

由于其余的 props 被传递给 &lt;Route /&gt;&lt;RouteWrapper /&gt; 的 props 类型应该 从react-router-dom扩展RouteProps

RouteWrapper 看起来像这样:

import * as React from 'react';
import  Redirect, Route, RouteProps  from 'react-router-dom';

interface RouteWrapperProps extends RouteProps 
  isPrivate: boolean;


export default function RouteWrapper(
  isPrivate = false,
  ...rest
: RouteWrapperProps): ReactElement 
  const signed = false;

  if (!signed && isPrivate) 
    return <Redirect exact to="/signin" />;
  

  if (signed && !isPrivate) 
    return <Redirect to="/" />;
  

  return <Route ...rest />;

如果你真的想使用propTypesdefaultProps,可以使用React.FC添加类型安全。

import * as PropTypes from 'prop-types';
import * as React from 'react';
import  Redirect, Route, RouteProps  from 'react-router-dom';

interface RouteWrapperProps extends RouteProps 
  isPrivate: boolean;


const RouteWrapper: React.FC<RouteWrapperProps> = ( isPrivate, ...rest ) => 
  const signed = false;

  if (!signed && isPrivate) 
    return <Redirect exact to="/signin" />;
  

  if (signed && !isPrivate) 
    return <Redirect to="/" />;
  

  return <Route ...rest />;
;

RouteWrapper.propTypes = 
  isPrivate: PropTypes.bool,
;

RouteWrapper.defaultProps = 
  isPrivate: false,
;

export default RouteWrapper;

注意使用react-router 编写路由的首选方式是使用子级,而不是 component道具。

import * as React from 'react';
import  Switch  from 'react-router-dom';

// Components
import RouteWrapper from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes(): React.ReactElement 
  return (
    <Switch>
      <Route exact path=['/signin', '/signup', '/reset-password']>
        <Authentication />
      </Route>
      <Route isPrivate path="/">
        <ChatApplication />
      </Route>
    </Switch>
  );

这应该可以帮助您开始转换应用程序的其余部分。 :)

【讨论】:

首先我要感谢您的回复,我尝试使用您的代码放置我发现这个问题“类型' isPrivate:PropTypes.Requireable;'不可分配给类型'WeakValidationMap '。”

以上是关于如何将 React 路由器功能转换为 Typescript?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React Hooks 将具有构造函数的类转换为功能组件?

如何将字符串转换为 React 组件

如何将类组件转换为功能组件?

将 React 函数组件转换为类组件问题

将基于 React 路由器 v4 类的代码重写为基于 v6 功能的代码

React将类组件转换为功能组件不起作用