I am using (I think) an "index access parameter" to write to an object in my reducer:
export type SettingsState = {
brainRadiusEstimate: number,
displayProgressIndicator: boolean,
respiratoryFilterUpperBound: string,
patientFeedback: PatientFeedbackType,
connectionStatus: ConnectionStatus,
brainSize: BrainSize,
version: 'BETA 2',
}
export type ChangeParameterAction = {
type: 'CHANGE_PARAMETER',
parameter: ParameterName,
value: any
}
export default function settingsReducer(state: SettingsState = defaultState, action: ChangeParameterAction): SettingsState {
switch (action.type) {
case 'CHANGE_PARAMETER':
const newState: SettingsState = { ...state };
newState[action.parameter] = action.value;
return newState;
default:
return state;
}
}
I'm getting an error on newState[action.parameter] = action.value
that says "Type 'any' is not assignable to type 'never'".
I see here (under "Fixes to unsound writes to indexed access types") that this is indeed to be expected in TypeScript. It says the solution is "If you are convinced that you are not dealing with an error, you can use a type assertion instead."
I've tried adding
type ValueTypes = number | string | boolean | null | PatientFeedbackType | ConnectionStatus | BrainSize | 'BETA 2
and changing the line to
newState[action.parameter] = action.value as ValueTypes;
as well as
const value: ValueTypes = action.value
newState[action.parameter] = value;
but I get the same error, simply with a different type that's not assignable to never.
Is there a way to do this parameter access without simply using @ts-ignore
?
You don't have an index signature on the type. But! It's okay, because there's another way to skin this cat: A computed property name:
const newState: SettingsState = { ...state, [action.parameter]: action.value };
Depending on the definition of ParameterName
, that should correct the problem. For instance, if ParameterName
is keyof SettingsState
, it will.
Live on the playground (using type ParameterName = keyof SettingsState;
)