使用带有打字稿的 react-router

Posted

技术标签:

【中文标题】使用带有打字稿的 react-router【英文标题】:Using react-router with typescript 【发布时间】:2015-10-23 05:38:18 【问题描述】:

我正在尝试将一个小型 React 应用程序移植到 typescript。

我遇到了 react-router 的问题。我有绝对类型的最新定义,但以下代码给了我错误:

var routes:Router.Route = (
<Route name="root" path="/" handler=MyApp>
  <Route path="dashboard" handler=MyDash />
  <DefaultRoute handler=SomeSection />
  <NotFoundRoute handler=NotFoundPage />
</Route>
);

Router.run(routes, function (Handler:React.Component<any, any>) 
  React.render(<Handler/>, document.body);
);

这些是我得到的编译错误:

js/app.tsx(31,3): error TS2605: JSX element type 'Component<RouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<RouteProp, any>'.
js/app.tsx(32,5): error TS2605: JSX element type 'Component<RouteProp, any>' is not a constructor function for JSX elements.
js/app.tsx(47,5): error TS2605: JSX element type 'Component<DefaultRouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<DefaultRouteProp, any>'.
js/app.tsx(49,5): error TS2605: JSX element type 'Component<NotFoundRouteProp, any>' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Component<NotFoundRouteProp, any>'.
js/app.tsx(53,20): error TS2345: Argument of type '(Handler: Component<any, any>) => void' is not assignable to parameter of type '(Handler: RouteClass, state: RouterState) => void'.
  Types of parameters 'Handler' and 'Handler' are incompatible.
    Type 'Component<any, any>' is not assignable to type 'RouteClass'.
js/app.tsx(54,17): error TS2604: JSX element type 'Handler' does not have any construct or call signatures.

使用 typescript 初始化一组 react-router 路由的正确方法是什么?

(我应该澄清一下,我正在使用通过 --jsx react 标志支持 JSX 的夜间打字稿构建

【问题讨论】:

我遇到了同样的问题,可能是 TypeScript 的 TSX 支持有问题:Typescript/3928。我在那里问了一个类似的问题,他们重新打开了这个问题。 【参考方案1】:

根本问题是 react-router 中的一些定义没有明确的 render() 方法。 https://github.com/borisyankov/DefinitelyTyped/pull/5197

已(间接)修复了此问题

请注意,此代码不正确:

Router.run(routes, function (Handler:React.Component<any, any>) 
  React.render(<Handler/>, document.body);
);

应该是:

Router.run(routes, function (Handler: new() => React.Component<any, any>) 
  React.render(<Handler/>, document.body);
);

因为Handler 是 React 组件的构造函数,而不是它的实例。

【讨论】:

嗯,不是免费的,毕竟他必须花时间在答案上;)【参考方案2】:

类型定义中的错误似乎是原因。您可以通过修改.d.ts 文件来解决它们,如下所示:

react.d.ts 中,从JSX.ElementClass 接口中删除render

interface ElementClass extends React.Component<any, any> 

react-router.d.ts 中,将run 方法的routes 参数类型更改为React.ReactElement&lt;RouteProp&gt;

function run(routes: React.ReactElement<RouteProp>, callback: RouterRunCallback): Router;
function run(routes: React.ReactElement<RouteProp>, location: LocationBase, callback: RouterRunCallback): Router;

【讨论】:

感谢您的回答,但我不喜欢更改 .d.ts 文件的想法。必须有一种方法让它们按原样工作,否则人们不会将它们发布到 definitielyTyped。【参考方案3】:

为了让它在带有 react-router 的 typescript 1.6 下运行,我在 react-router.d.ts 文件中添加了以下代码:

interface RouterClass extends React.ComponentClass<any> 

var Router: RouterClass;

//For Router

function createElement(

type: ReactRouter.RouterClass,

props: any,

...children: __React.ReactNode[]): ReactRouter.Router;



interface RouteProp 
    name?: string;
    path?: string;
    handler?: React.ComponentClass<any>;
    ignoreScrollBehavior?: boolean;
    component?: React.ComponentClass<any>;

【讨论】:

应用更改后工作正常。

以上是关于使用带有打字稿的 react-router的主要内容,如果未能解决你的问题,请参考以下文章

带有打字稿的枚举

带有打字稿的角度材料设计

带有打字稿的 Angular 5 websocket 示例

使用带有打字稿的 eslint - 无法解析模块的路径

带有打字稿的嵌套角度指令

带有打字稿的 mapDispatchToProps 很困难