13

I'm trying to get a new object/type from the other one, but get a Type 'string' is not assignable to type 'never' error

const Flags = {
  ONE: () => 'one',
  TWO: () => 'two',
  // ...
};

type createEnumType<T> = {[K in keyof T]: K};
type FlagsObject = createEnumType<typeof Flags>;
type FlagsKeys = keyof FlagsObject;

const keys = Object.keys(Flags) as FlagsKeys[];
let result = {} as FlagsObject;
for (const key of keys) {
  result[key] = key;// Type 'string' is not assignable to type 'never'
}

/*
Expected value and type:
result = {
  ONE: "ONE";
  TWO: "TWO";
}
*/

I set the type to the result, so what am I doing wrong? Why is never here?

FLighter
  • 389
  • 1
  • 4
  • 17
  • Define the array type, otherwise it will be `never` – zanderwar Jun 21 '21 at 23:37
  • 1
    Does this answer your question? [What is "not assignable to parameter of type never" error in typescript?](https://stackoverflow.com/questions/52423842/what-is-not-assignable-to-parameter-of-type-never-error-in-typescript) – zanderwar Jun 21 '21 at 23:38

1 Answers1

22

the problem is that the expression result[key] has type never, which is a type with no values. Let's see why it happens:

  • key has type 'ONE'|'TWO'
  • result has type { 'ONE': 'ONE'; 'TWO': 'TWO' } hence:
    • result['ONE'] has type 'ONE'
    • result['TWO'] has type 'TWO'
  • result[key] may sometime be result['ONE'] and sometimes be result['TWO']. If you want to assign something to it you have to choose a value that can be both. No value can be at the same time 'ONE' and 'TWO'.

To do what you expect you have to type key more strongly but you cannot do that since you have to loop. I suggest you override the typing for result inside the loop so that the type is still strong outside:

(result as Record<typeof key, typeof key>)[key] = key;
pqnet
  • 6,070
  • 1
  • 30
  • 51
  • Thank you for the walk-through explanation, it really helped me understand the situation. I know I've read something similar recently (probably on the TypeScript website) but your description cemented it for me today. – kalisjoshua Apr 04 '23 at 18:00