Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type 'any' is not assignable to type 'never'

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?

like image 527
Jonathan Tuzman Avatar asked Dec 29 '25 18:12

Jonathan Tuzman


2 Answers

In my case the error:

type 'any' is not assignable to type 'never'

Was simply being caused due to an array that was not properly declared (with a specific type). Therefore, I solved it by changing its declaration, e.g. from:

myArray: [];

To:

myArray: any[];
like image 97
CPHPython Avatar answered Dec 31 '25 11:12

CPHPython


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;)

like image 41
T.J. Crowder Avatar answered Dec 31 '25 11:12

T.J. Crowder