【发布时间】:2017-06-08 02:01:29
【问题描述】:
我正在尝试让一个 react-redux 应用程序与 typescript 一起使用,但我一直围绕着同样的错误。以下代码编译并产生预期结果
// 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<any, any> {
render() {
return <div onClick={this.handleClick.bind(this)}>Hello world "{this.props.count}"</div>
}
handleClick() {
store.dispatch(click())
}
}
// Container components
const mapStateToProps = (state:AppState):HelloWorldState => {
return Immutable.fromJS({
count: state.clickCount
})
};
const ConnectedHelloWorld = connect(
mapStateToProps
)(HelloWorld);
render(
<Provider store={store}>
<ConnectedHelloWorld/>
</Provider>,
container
);
太棒了!但我使用的是 TypeScript,因为我想在编译时进行类型检查。类型检查最重要的是状态和道具。所以不是class HelloWorld extends React.Component<any, any>,我想做class HelloWorld extends React.Component<HelloWorldProps, any>。但是,当我这样做时,我从对 render 的调用中得到以下编译错误
TS2324:Property 'count' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<HelloWorld> & HelloWorldProps & { children?: React...'.
我真的不明白为什么。 count IS 出现在HelloWordProps 定义中,它是由reducer 提供的,所以我应该没问题,对吧?类似的问题表明这是一个推理问题,我应该将调用的类型声明为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"
}
}
typings.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(
<Provider store={store}>
<ConnectedHelloWorld count={0}/>
</Provider>,
container
);
这解决了这个问题。所以问题是编译器不知道Provider 提供了计数。提供者使用商店。 store 应该有 clickCount 值,该值由容器组件映射到 count。
我注意到我忘记了商店的初始状态。因此,即使类型已签出,状态也会为空。我把它更新为
// Store
let initialState:AppState = {clickCount: 0};
let store = createStore(rootReducer, initialState);
现在我确定 clickCount 在商店中设置正确。所以我希望mapStateToProps 函数采用AppState 并按指定返回HelloWorldProps,然后Provider 应该提供计数值。这是真的,但编译器看不到。
那么如何解决呢?
【问题讨论】:
-
即使您只执行简单的
HelloWorld课程,您是否也会收到此错误? (也就是说,没有 redux)因为它对我有用。另外,您使用的是什么版本的反应? -
简单的意思是
HelloWorld extends React.Component<any, any>?是的,这总是有效的,因为它的状态和道具的类型是any。所以那里没有错误。 -
不,我的意思是只有
class HelloWorld extends React.Component<HelloWorldProps, any>没有redux 的东西。对我来说编译得很好。你使用的是什么版本的 react/typescript? -
我更新了问题。你是对的,问题来自 redux 或 react-redux
-
您可以在此处找到连接示例:github.com/Black-Monolith/LightCycle/blob/master/app/containers/…。它将当前组件与我们
connect()组件的容器文件分离到存储区。我们还导出了MappedProps类型,以便能够将其用作组件中的道具类型。
标签: reactjs typescript redux react-redux