I'm trying to use Typescript in my React app
In my mapStateToProps
I have this code
const mapStateToProps = (state: AppState) => {
console.log(state)
return {
...state.player,
position: state.player.position
}
}
My AppState
import { combineReducers } from 'redux';
import playerReducer from './player';
export const rootReducer = combineReducers({
player: playerReducer
} as any);
export type AppState = ReturnType<typeof rootReducer>
And I'm getting an error TypeScript error: Property 'player' does not exist on type '{}'. TS2339
TypeScript error: Property 'player' does not exist on type '{}'. TS2339
in relation to the line ...state.player
But if I console.log state (on the line before that) My state
has player
property.
I'm not sure why am I getting this error. All the help will be appreciated.
Player Reducer
import { Action } from '../actions/types';
import { Store } from '../types';
export const initialState: Store = {
position: [410, 0]
};
const playerReducer = (state = initialState, action: Action) => {
switch (action.type) {
case 'MOVE_PLAYER':
return {
...state,
position: action.payload
}
default:
return state;
}
}
export default playerReducer;
The problem is that combineReducers
is unable to infer the type of the object that you're passing in due to as any
. This means that your root reducer can only be inferred to by type:
const rootReducer: Reducer<{}, AnyAction>;
Simply take out the as any
in combineReducers
:
export const rootReducer = combineReducers({
player: playerReducer
});
Should be inferred as:
const rootReducer: Reducer<{
player: PlayerState;
}, AnyAction>;
Try strong-typing your playerReducer
:
import { Action, Reducer } from "redux";
const playerReducer: Reducer<Store, Action> = (state = initialState, a) => {
...
};
The exact pattern I use in my project would be something like this (of course, you may want to tweak it until you get something that works a bit better for your project):
import { Action, Reducer } from "redux";
import { MOVE_PLAYER } from "../actions/playerActions"; // list all relevant actions here
export interface PlayerState {
readonly position: [number, number];
}
const initialState: PlayerState = {
position: [410, 0];
};
const reducers: { [k: string]: (s: PlayerState, a: any) => PlayerState } = {
[MOVE_PLAYER]: (s, a: { payload: [number, number] }) => ({ ...s, position: a.payload }),
// other player reducers
}
const reducer: Reducer<PlayerState, Action> = (s = initialState, a) => {
const f = reducers[a.type];
return typeof f === "function" ? f(s, a) : s;
};
export default reducer;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.