我正在尝试使用一个带有typescript的react-redux应用程序,但是我一直绕着相同的错误盘旋。以下代码编译并产生预期结果
// State definition interface HelloWorldState { clickCount: number } interface AppState extends HelloWorldState {} // Props definitions interface HelloWorldProps { count: number } // Actions const CLICK = 'CLICK'; const click = () => {return {type:CLICK}}; // Reducers function clickCount(state:number = 0, action:Action) { if (typeof state === 'undefined') { return 0; } switch (action.type) { case CLICK: return state + 1; default: return state; } } let rootReducer = combineReducers({ clickCount }); // Store let store = createStore(rootReducer); // Components class HelloWorld extends React.Component{ render() { return Hello world "{this.props.count}"} handleClick() { store.dispatch(click()) } } // Container components const mapStateToProps = (state:AppState):HelloWorldState => { return Immutable.fromJS({ count: state.clickCount }) }; const ConnectedHelloWorld = connect( mapStateToProps )(HelloWorld); render(, container );
大!但是我正在使用TypeScript,因为我想在编译时进行类型检查。类型检查最重要的是状态和道具。因此class HelloWorld extends React.Component
,我想做的不是class HelloWorld extends React.Component
。但是,在执行此操作时,从调用时出现以下编译错误render
TS2324:Property 'count' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes& HelloWorldProps & { children?: React...'.
我真的不明白为什么。count
IS目前在HelloWordProps
定义,它是由减速机提供的,所以我应该没事吧?类似的问题表明这是一个推理问题,我应该声明对的调用类型connect
,但是我似乎无法找出如何
package.json
{ "name": "reacttsx", "scripts": { "build": "webpack" }, "devDependencies": { "ts-loader": "^1.3.3", "typescript": "^2.1.5", "webpack": "^1.14.0", "typings": "^2.1.0" }, "dependencies": { "es6-promise": "^4.0.5", "flux": "^3.1.2", "immutable": "^3.8.1", "isomorphic-fetch": "^2.2.1", "jquery": "^3.1.1", "react": "^15.4.2", "react-dom": "^15.4.2", "react-redux": "^5.0.2", "redux": "^3.6.0", "redux-logger": "^2.7.4", "redux-thunk": "^2.2.0" } }
Types.json
{ "dependencies": { "flux": "registry:npm/flux#2.1.1+20160601175240", "immutable": "registry:npm/immutable#3.7.6+20160411060006", "react": "registry:npm/react#15.0.1+20170104200836", "react-dom": "registry:npm/react-dom#15.0.1+20160826174104", "react-redux": "registry:npm/react-redux#4.4.0+20160614222153", "redux-logger": "registry:dt/redux-logger#2.6.0+20160726205300", "redux-thunk": "registry:npm/redux-thunk#2.0.0+20160525185520" }, "globalDependencies": { "es6-promise": "registry:dt/es6-promise#0.0.0+20160726191732", "isomorphic-fetch": "registry:dt/isomorphic-fetch#0.0.0+20170120045107", "jquery": "registry:dt/jquery#1.10.0+20170104155652", "redux": "registry:dt/redux#3.5.2+20160703092728", "redux-thunk": "registry:dt/redux-thunk#2.1.0+20160703120921" } }
更新
由于它抱怨说count
丢失了,所以我尝试更新为
render(, container );
这样就解决了问题。因此,问题在于编译器不知道那个Provider
正在提供计数。提供者使用商店。存储应该具有容器组件clickCount
映射到的值count
。
我注意到我忘记了商店的初始状态。因此,即使类型已经签出,状态也将为空。我更新为
// Store let initialState:AppState = {clickCount: 0}; let store = createStore(rootReducer, initialState);
现在,我可以确定clickCount
商店中的设置是否正确。因此,我希望mapStateToProps
函数采用AppState
并返回HelloWorldProps
指定的,然后Provider
应当提供计数值。的确如此,但是编译器看不到它。
那么如何补救呢?
这是我在Typescript Redux应用程序中执行的操作(已调整为您的代码,但未经测试)
编辑以下评论
connect
附带道具的类型(ConnectedHelloWorldProps
)
const ConnectedHelloWorld:React.ComponentClass= connect (mapStateToProps)(HelloWorld) interface ConnectedHelloWorldProps { } interface HelloWorldProps extends ConnectedHelloWorldProps { count: number .... }
在中使用连接的组件及其ConnectedHelloWorldProps
道具Provider
注意:这些类型适用
"@types/react": "^0.14.52", "@types/react-dom": "^0.14.19", "@types/react-redux": "^4.4.35", "@types/redux-thunk": "^2.1.32",
ConnectedHellowWorldProps
因为它是一个空接口,所以在这里并不需要它,但是在现实世界中,它可能包含一些道具。
基本原则是:ConnectedHelloWorldProps
包含需要在提供程序级别传递的内容。在mapStateToProps
和/或中mapDispatchToProps
,HelloWorldProps
根据需要添加实际的组件
Redux Typescript打字是一头野兽,但上面显示的内容就足够了。
export declare function connect( mapStateToProps: FuncOrSelf >, mapDispatchToProps?: FuncOrSelf | MapDispatchToPropsObject>): ComponentDecorator ; interface ComponentDecorator { (component: ComponentClass | StatelessComponent ): ComponentClass ; }