首页 文章

将Typescript与React-Redux一起使用时输入Error

提问于
浏览
10

我正在尝试使用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也可以解决问题 . 看起来类型系统不理解这两个对象是由两个映射函数合并的 .

2 回答

  • 8

    为了保护类型安全,您可以将道具分成几部分,一部分负责普通道具,一部分负责调度员:

    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);
    
  • 38

    我在这个Github issue的第二个到最后一个帖子找到了答案 . 如果 mapStateToProps 和/或 mapDispatchToPropsconnect 上没有type参数,它将生成两个map函数的返回类型的交集 .

相关问题