ts2322 "is not assignable to type never" error in simpliest case

Viewed 78

I've been reading several similar topics but they all about some particular cases and i get this error in a simpliest posiible case. What is generally point of this error and how to solve it?

type SomeInterface = {
  prop1: number
  prop2: boolean
}

const testFn = (obj: SomeInterface, key: keyof SomeInterface, value: any) => {
  obj[key] = value
}
2 Answers

I think the issue might by that obj[key] is either number or boolean, and since there is no overlap between these two types, it effectively becomes never.

This is one way this might be fixed, using a generic:

const testFn  = function<T extends keyof SomeInterface>(obj: SomeInterface, key: T, value: SomeInterface[T]) {
  obj[key] = value
}

We're basically saying that T is a keyof SometInterface, that needs to be passed as the second argument.

But we're also saying that the third argument (value) must match the type of the key of SomeInterface.

Problem

One more thing should be aware of is obj[key] with key is keyof SometInterface would always return never type which isn't assigned even any type.

Solution

You might know this is quite common use case which can resolve by using generic type:

const testFn = <T extends SomeInterface, K extends keyof T>(obj: T, key: K, value: T[K]) => {
  obj[key] = value
}

But if you wish not to use generic type, you can set the value type as never:

const testFn = (obj: SomeInterface, key: keyof SomeInterface, value: never) => {
  obj[key] = value;
}
Related