Here is a piece of code i got:
interface Obj {
a: number
b: string
}
const obj: Obj = {
a: 1,
b: 'hi'
}
function fn(key: keyof Obj, value: Obj[keyof Obj]) {
let foo = obj[key]
obj[key] = value
}
fn("a", 2)
So what i want to do is, i want the function fn() to be able to update the object obj properties, the first argument of this function is any key that obj has(defined in Obj interface), and the second argument is the value you wanna give to that key.
However, the typescript popup with an error in the obj[key] = value this line, which is:
Type 'string | number' is not assignable to type 'never'.
Type 'string' is not assignable to type 'never'.(2322)
Here is a screenshot:
And a strange thing happens here, if you hover to the variable foo(which is line 13 in the picture), it says:
let foo: string | number
which means, obj[key]'s type is string | number, but the error says obj[key] type is never.
so my first question is: How come a
string | numbertype magically becomes a never type? Is there any way to fix this?
Then i got another piece of code which solves this problem:
interface Obj {
a: number
b: string
}
const obj: Obj = {
a: 1,
b: 'hi'
}
function fn<K extends keyof Obj>(key: K, value: Obj[K]) {
obj[key] = value
}
fn("a", 2)
Therefore my second question would be: why using
Genericssolve the problem and what the hack is the keywordextendshere?
BTW, all the code are tested in typescript 3.7.5 version.
I am not a native English speaker, hope i explained my confusion clearly.
