2016-05-03 2 views
6

Я пытаюсь использовать response-redux с машинописным шрифтом, и я получаю ошибку типа, когда пытаюсь вставить реквизиты с помощью connect() и mapStateToProps.Тип Ошибка при использовании TypScript с React-Redux

Мой компонент выглядит следующим образом:

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 компонента для любого решения также решает проблему. Кажется, что система типов не понимает, что эти два объекта объединены двумя отображаемыми функциями.

ответ

7

Я нашел ответ на второй по счету на этом Github issue. Без параметра типа на mapStateToProps и/или mapDispatchToProps или на connect он будет производить пересечение возвращаемых типов двух функций карты.

+0

Вы узнали что-нибудь еще (объяснение) об этом? Я заметил, что вы не получили ответа на свой вопрос по проблеме github. Используете ли вы типы возвращаемых данных для mapStateToProps и mapDispatchToProps (для чего вам, вероятно, пришлось сделать члены интерфейса опционными, как вы предполагали)? Именно так я в настоящее время применяю его, чтобы иметь возможность запускать. – Jeroen

+1

Да, я указал типы возврата на mapStateToProps и mapDispatchToProps. Элементы интерфейса должны быть факультативными, независимо от того, в противном случае он не будет работать, когда компонент вызывается. Я не большой поклонник того, как TS работает с методом подключения Redux и connect-redux, но сейчас я не могу придумать хороший способ. – Ochowie

26

Чтобы сохранить безопасность типа вы можете разделить ваши реквизита в части, один ответственный за нормальный реквизит и один для диспетчеров:

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

Для тех, кто ищет для быстрого решения проблемы: просто добавить «как любые» для базового компонента ,

export default connect(mapStateToProps, mapDispatchToProps)(MyComp as any); 
+0

В моем случае у меня не было никаких значений для 'mapDispatchToProps', поэтому явная передача' null' или 'undefined' вместо того, чтобы оставить значение, как представляется, заставляет ошибку уйти:' export default connect (mapStateToProps, null) (MyComponent); ' – Shepmaster

+0

as. в виде? в виде! \\ (^ o ^)/ – Raffael

+0

Это происходит не так, как вам нужно, чтобы ввести тип параметризации connect: Даже тогда, кажется, есть более глубокие проблемы с подключением. – stevematdavies

 Смежные вопросы

  • Нет связанных вопросов^_^