Typescript cannot assign object literal to a generic type

Viewed 937

I get a type error if I try to use an object literal with a generic type that has a type constraint, I am struggling to figure out why:

type WithKey = {
  readonly akey: string;
}

function listOfThings<T extends WithKey>(one: T) {
  // This is ok
  const result2: Array<T> = [one];

  //This errors with Type '{ akey: string; }' is not assignable to type 'T'.
  const result: Array<T> = [{ akey: 'foo' }]; 

  return result;
}
2 Answers

The reason it doesn't accept { akey: 'foo' } is because T only extends WithKey, so an object which is literally WithKey isn't necessarily assignable to T. For example:

listOfThings<{ akey: string; aflag: boolean }>()

{ akey: 'foo' } does not satisfy { akey: string; aflag: boolean }.

You could coerce the compiler using an assertion:

const result: Array<T> = [{ akey: 'foo' } as T]; 

But this is opening you up for a bug, as in the first example would compile but not be true at runtime. It seems like either this isn't what you want, or the types don't describe what you want.

{ akey: 'foo' } actually has type, it is not generic type. That's why it doesn't like your assignment.

compiler does not understand { akey: 'foo' } as WithKey type.

you can force typescript by casting for this assignment

const result: Array<T> = [<T>{ akey: 'foo' }];

Related