3

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
  • What do you expect the call const hmm = listOfThings({akey: "foo", bkey: 123}); to produce? Commented Dec 17, 2018 at 15:58
  • 2
    It has recently been proposed that the error, while accurate, should be made less confusing. Commented Dec 17, 2018 at 16:00

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

{ 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' }];

1 Comment

You can force it to do this but you shouldn't unless you know what you're doing. listOfThings({akey: "foo", bkey: 123}) will infer T as {akey: string, bkey: number}, and then {akey: string} is definitely not assignable to it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.