如何协调 TypeScript 的“strictFunctionTypes”与 React Router 和 Redux?

Vin*_*ent 5 typescript definitelytyped react-router redux react-router-redux

TypeScript 2.6引入strictFunctionTypes,升级后,我似乎无法让 Redux 和 React Router 相互配合。因此,我想知道如何最好地定义一个组件的类型,该组件既要显示在某个路线上,又要从 Redux 接收道具。

以下是关于我如何设置我的应用程序。有这样一条路线:

<Route path="/some/path/with/:parameter" component={ConnectedComponent}/>
Run Code Online (Sandbox Code Playgroud)

然后我想要显示的组件从 Redux 和 React Router 接收 props,我试图在以下类型签名中捕获它们:

class BareComponent extends React.Component<ReduxProps & RouteProps, ArbitraryState>
Run Code Online (Sandbox Code Playgroud)

...其中 Redux 道具的定义类似于以下内容:

interface StateProps { storeProperty: string; }
interface DispatchProps { dispatchCallback: () => void; }
type ReduxProps = StateProps & DispatchProps;
Run Code Online (Sandbox Code Playgroud)

...和路由器道具有点像以下:

interface RouteParams { parameter: string }
type RouteProps = RouteComponentProps<RouteParams>;
Run Code Online (Sandbox Code Playgroud)

RouteComponentProps从哪里进口react-router-dom

传递给路由器的组件(通过Route上面第一个代码示例中的)创建如下:

const ConnectedComponent = connect<StateProps, DispatchProps, RouteProps, ArbitraryStateInterface>(mapStateToProps)(BareComponent);
Run Code Online (Sandbox Code Playgroud)

不幸的是,使用strictFunctionTypes,这导致 TypeScript 抱怨ConnectedComponent无法分配给 React Router 期望的类型:

    TS2322: Type '{ path: "/some/path/with/:parameter"; component: ComponentClass<Pick<StatePr...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Route> & Readonly<{ children?: ReactNode; }> & Rea...'.
Type '{ path: "/some/path/with/:parameter"; component: ComponentClass<Pick<StatePr...' is not assignable to type 'Readonly<RouteProps>'.
  Types of property 'component' are incompatible.
    Type 'ComponentClass<Pick<StateProps & DispatchProps & RouteC...' is not assignable to type 'StatelessComponent<RouteComponentProps<any> | undefined> | ComponentClass<RouteComponentProps<any...'.
      Type 'ComponentClass<Pick<StateProps & DispatchProps & RouteC...' is not assignable to type 'ComponentClass<RouteComponentProps<any> | undefined>'.
        Types of parameters 'props' and 'props' are incompatible.
          Type 'RouteComponentProps<any> | undefined' is not assignable to type 'Pick<StateProps & DispatchProps & RouteComponentProps<R...'.
            Type 'undefined' is not assignable to type 'Pick<StateProps & DispatchProps & RouteComponentProps<R...'.
              Type 'undefined' is not assignable to type 'Pick<StateProps & DispatchProps & RouteComponentProps<R...'.
Run Code Online (Sandbox Code Playgroud)

那么,我定义上述类型的方式与这些类型的使用方式不符?有没有一种方法可以让我在strictFunctionTypes不使用anys 的情况下启用?

小智 0

除了您已经使用的 之外,尝试使用 的react-router-domHOC函数。https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.mdwithRouterconnect

提示:用于recompose保持事物整洁(也有助于解决我发现的严格的打字稿问题)。

import { withRouter } from 'react-router-dom';
import { compose } from 'recompose';
...

...
export const ConnectedComponent = compose<ReduxProps & RouteProps, void>(
    connect(mapStateToProps, mapDispatchToProps),
    withRouter
)(BareComponent);
Run Code Online (Sandbox Code Playgroud)

将“void”替换为您想要暴露的任何道具。

这可能是其中的 95%。目前没有 VPN 访问权限,需要仔细检查。我正在用手机,很抱歉格式很糟糕。一旦我可以检查什么对我有用,我就会更新!