I have the following interfaces:
interface AppState {
readonly grid : IGridSettings;
readonly selected : ISelectedSettings;
}
interface IGridSettings {
readonly extents : number;
readonly isXY : boolean;
readonly isXZ : boolean;
readonly isYZ : boolean;
readonly spacing : number;
}
interface ISelectedSettings {
readonly bodyColor : number;
readonly colorGlow : number;
readonly lineColor : number;
readonly selection : number[] | undefined;
}
interface Action<T = any> {
type: T
}
interface SetPropertyValueAction<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]> extends Action {
type : string;
payload : {
property : [KAction, KActionProp];
value : IUserActions[KAction][KActionProp];
};
}
Eventually my redux reducer gets called when the setPropertyValue function is emitted:
const setPropertyValue = <KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>( property : [KAction, KActionProp], value : AppState[KAction][KActionProp] ) : SetPropertyValueAction<KAction, KActionProp> => ( {
type: 'SET_PROPERTY_VALUE',
payload: {
property,
value,
}
} );
function myReducer( state : AppState = INITIAL_STATE, a : Action ) : AppState {
switch( a.type ) {
case 'SET_PROPERTY_VALUE': {
const action = a as SetPropertyValueAction; // <- error here
return createNewState( state, action.payload.property, action.payload.value );
}
}
return states;
}
The problem that I'm having is I don't know how to fix the cast from Action to SetPropertyValueAction. TypeScript tells me the error is:
Generic type 'SetPropertyValueAction<KAction, KActionProp>' requires 2 type argument(s).
I tried changing the line of code that has the error to the following:
const action = a as SetPropertyValueAction<KAction extends keyof AppState, KActionProp extends keyof AppState[KAction]>;
...but this gives me two errors saying 'Cannot find name KAction and KActionProp'
How can I cast an Action object to the generic SetPropertyValueAction ??
This is a follow up question to my other question that has been answered here: How to add TypeScript type safety to my redux action?
We need to specify the type parameters for the type. Since we don't really know them, we need something that is compatible with
keyof T
but represent is not an actual key ofT
.unknown
will not do since it does not satisfy the constraint, the one type we can use isany
ornever
(which is a subtype of any type)