Reputation: 3850
I am trying to create a TypeScript redux reducer that accepts an actionType as a key value, however I am struggling to define the proper interface for my state. When doing so, I am getting the following message:
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SampleState'. No index signature with a parameter of type 'string' was found on type 'SampleState'.
How do I properly type check my reducer for when it receives an actionType? Thanks, you can see the sample code below.
sampleActionTypes.ts:
export const FOO = 'FOO';
export const BAR = 'BAR';
export const TURN_ON = 'TURN_ON';
export const TURN_OFF = 'TURN_OFF';
interface TurnOn {
type: typeof TURN_ON;
actionType: string;
}
interface TurnOff {
type: typeof TURN_OFF;
actionType: string;
}
export type Types = TurnOn | TurnOff;
sampleReducer.ts:
import { BAR, FOO, TURN_OFF, TURN_ON, Types } from './sampleActionTypes';
export interface SampleState {
[FOO]: {
toggle: boolean;
};
[BAR]: {
toggle: boolean;
};
}
const initialState: SampleState = {
[FOO]: {
toggle: false,
},
[BAR]: {
toggle: false,
},
};
const sampleReducer = (state = initialState, action: Types): SampleState => {
switch (action.type) {
case TURN_ON:
return {
...state,
[action.actionType]: {
...state[action.actionType],
toggle: true,
},
};
case TURN_OFF:
return {
...state,
[action.actionType]: {
...state[action.actionType],
toggle: false,
},
};
default:
return state;
}
};
export default sampleReducer;
Upvotes: 0
Views: 763
Reputation: 3850
Updating the SampleState
interface to the following solved this issue:
export interface SampleState {
[key: string]: {
toggle: boolean;
};
}
Upvotes: 0
Reputation: 1004
Your state has as keys FOO | BAR
following your SampleState
interface.
And your Types['actionType']
is string
.
So when you're doing state[action.actionType]
, you're doing SampleState[string]
. But SampleState
accepts only FOO
or BAR
!
A solution, according to your needs, may be to type Types['actionType']: (typeof FOO) | (typeof BAR)
(something like that).
Also carefull to how you're naming your fields. Maybe it's just for the example, but actionType
when there is already a type
in an action interface seems redondant and quite confusing.
Upvotes: 1