简体   繁体   中英

Property does not exist on type '{}'

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM