将 Typescript 与 React-Redux 一起使用时出现类型错误
Posted
技术标签:
【中文标题】将 Typescript 与 React-Redux 一起使用时出现类型错误【英文标题】:Type Error when using Typescript with React-Redux 【发布时间】:2016-08-28 20:33:12 【问题描述】:我正在尝试将 react-redux 与 typescript 一起使用,当我尝试使用 connect() 和 mapStateToProps 注入道具时出现类型错误。
我的组件如下所示:
function mapStateToProps(state)
return
counter: state.counter
;
function mapDispatchToProps(dispatch)
return
incr: () =>
dispatch(type: 'INCR', by: 2);
,
decr: () =>
dispatch(type: 'INCR', by: -1);
;
export default class Counter extends React.Component<HelloProps, any>
render()
return (
<div>
<p>
<label>Counter: </label>
<b>#this.props.counter</b>
</p>
<button onClick=e => this.props.incr() >INCREMENT</button>
<span style= padding: "0 5px" />
<button onClick=e => this.props.decr() >DECREMENT</button>
);
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
这家店是这样的
let store = createStore(
(state:HelloState, action:HelloAction) =>
switch (action.type)
case 'INCR':
return counter: state.counter + action.by;
default:
return state;
,
最后,我将类型定义为:
interface HelloProps
counter?: number;
incr?: () => any;
decr?: () => any;
interface HelloState
counter:number;
interface HelloAction
type:string,
by:number;
当我尝试编译代码时,出现以下错误:
(39,61): error TS2345: Argument of type 'typeof Counter' is not assignable to parameter of type 'ComponentClass< counter: any; & incr: () => void; decr: () => void; > | StatelessComponent<...'.
Type 'typeof Counter' is not assignable to type 'StatelessComponent< counter: any; & incr: () => void; decr: () => void; >'.
Type 'typeof Counter' provides no match for the signature '(props?: counter: any; & incr: () => void; decr: () => void; , context?: any): ReactElement<any>'
有趣的是,即使抛出类型错误,代码仍然可以工作。此外,将组件的 prop 接口更改为 any 也可以解决问题。似乎类型系统不理解这两个对象是由两个映射函数合并的。
【问题讨论】:
您将 Counter 组件导出两次,这可能也是这里的问题。 【参考方案1】:我在这个 Github issue 的倒数第二个帖子中找到了答案。如果mapStateToProps
和/或mapDispatchToProps
或connect
上没有类型参数,它将产生两个映射函数的返回类型的交集。
【讨论】:
你有没有发现更多关于这个的(解释)?我注意到您在 github 问题上的问题没有收到任何答案。您是否使用 mapStateToProps 和 mapDispatchToProps 的返回类型(您可能必须按照您的建议将接口的成员设为可选)?这就是我目前应用它以使其能够运行的方式。 是的,我在 mapStateToProps 和 mapDispatchToProps 上指定了返回类型。接口成员必须是可选的,否则它会在调用组件时失败。我不太喜欢 TS 如何与 Redux 和 react-redux 的 connect 方法一起工作,但我现在想不出一个好的方法。【参考方案2】:为了保持类型安全,你可以将你的 props 分成几部分,一个负责普通 props,一个负责调度员:
import * as React from 'react';
import connect from 'react-redux';
interface StateProps
textPros: string,
optionalText?: string,
interface DispatchProps
onClick1: Function,
class MyComp extends React.Component<StateProps & DispatchProps , any>
render()
return (<div onClick=this.props.onClick1>this.props.textPros</div>);
const mapStateToProps = (state: any, ownProp? :any):StateProps => (
textPros: "example text",
);
const mapDispatchToProps = (dispatch: any):DispatchProps => (
onClick1: () =>
dispatch( type: 'CLICK_ACTION');
);
export default connect(mapStateToProps, mapDispatchToProps)(MyComp);
对于那些寻求快速解决方法的人:只需将“as any”添加到基本组件即可。
export default connect(mapStateToProps, mapDispatchToProps)(MyComp as any);
【讨论】:
在我的情况下,我没有任何mapDispatchToProps
的值,因此明确传递 null
或 undefined
而不是离开值似乎使错误消失:@987654326 @
作为。作为?作为! \(^o^)/
这特别失败,因为您需要对连接进行类型参数化:即使那样,连接似乎也存在更深层次的问题。
使用 TypeScript 然后在这里和那里放 any
有什么意义?不好的例子。以上是关于将 Typescript 与 React-Redux 一起使用时出现类型错误的主要内容,如果未能解决你的问题,请参考以下文章
将 typescript 与 Babel 7 Standalone 一起使用
Angularjs + Typescript,如何将 $routeParams 与 IRouteParamsService 一起使用