Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix "Type 'string' is not assignable to type 'never'"?

Tags:

typescript

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?

like image 858
FLighter Avatar asked Dec 13 '25 19:12

FLighter


1 Answers

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;
like image 118
pqnet Avatar answered Dec 15 '25 10:12

pqnet