Home > Mobile >  Type 'any' is not assignable to type 'never' when trying to set Object property
Type 'any' is not assignable to type 'never' when trying to set Object property

Time:11-11

In the code below typscript compiler shows error in update method, saying that 'any' is not assignable to type 'never'. I noticed that keyof type not working when the type contains boolean mixed with other types. How can I make it compile having mixed type values in the type?

type ConfigState = {
  isAdminSet: boolean;
  isDatabaseConnected: boolean;
  adminName: string;
};

export class ConfigManager {
  state: ConfigState = {
    isAdminSet: false,
    isDatabaseConnected: false,
    adminName: "",
  };

  update(key: keyof ConfigState, value: ConfigState[keyof ConfigState]) {
    this.state[key] = value;
  }
}

But this compiles:

type ConfigState = {
  isAdminSet: boolean;
  isDatabaseConnected: boolean;
};

export class ConfigManager {
  state: ConfigState = {
    isAdminSet: false,
    isDatabaseConnected: false,
  };

  update(key: keyof ConfigState, value: ConfigState[keyof ConfigState]) {
    this.state[key] = value;
  }
}

CodePudding user response:

TLDR: TypeScript doesn't know if your value will fit into the chosen property of state.

In your first example, all the properties are boolean, so any is inferred as a boolean. But as soon as you add an other type (here, a string), any can't be inferred without restricting the key. Hence, it is inferred as never, and you can't assign any to never.

In this case, you must (I think) use a generic for this. Moreover, this will ensure type safety.

Take a look at this section of TS documentation: https://www.typescriptlang.org/docs/handbook/2/generics.html#using-type-parameters-in-generic-constraints

type ConfigState = {
  isAdminSet: boolean;
  isDatabaseConnected: boolean;
  adminName: string;
};

export class ConfigManager {
  state: ConfigState = {
    isAdminSet: false,
    isDatabaseConnected: false,
    adminName: "",
  };

  update<Key extends keyof ConfigState>(key: Key, value: ConfigState[Key]) {
    this.state[key] = value;
  }
}
  • Related