I would like some explanation about this error I encounter:
interface Test {
a: number;
b: string;
c: string;
}
function f(obj1: Test, obj2: Test, field: keyof Test) {
obj1[field] = obj2[field]; // Error: Type 'string | number' is not assignable to type 'never'.
}
Here are some ways I found to circumvent that error:
obj1[field as string] = obj2[field]
function f<K extends keyof Test>(obj1: Test, obj2: Test, field: K)
But I don't understand why this code fails, is it a "bug" in typescript or am I missing something ?
That's because TypeScript doesn't know what type will be returned by obj2[field]
. It can be either number
or string
. In addition, TypeScript doesn't know what type of obj1[field]
will be. And because it is number | string
so it decides, for type safety, that it will be never
, because there are no types that is base for both number
and string
. Additionally, TypeScript doesn't know which property name will be in field
if Test contains only numbers or only strings
In that case, TypeScript definitely knows that all fields will be number
or string
, so it can infer types for both obj1[field]
and obj2[field]
, and it will be the same type.
if I change my method to function f(obj1: Test, obj2: Test, field: K)
In that case TypeScript knows exactly type for both obj1[field]
and obj2[field]
, so it can safely assign value.