I have created a React hook:
interface Person {
name: string
age: number
}
export const usePerson = function <T extends Person, K extends keyof T>(): (property: K, setter: (value: T[K]) => T[K]) => void {
const setPersonProperty = (property: K, setter: (value: T[K]) => T[K]): void => {
console.log(property, setter)
}
setPersonProperty('name', (x) => x)
return setPersonProperty;
}
I have seen the pattern <T, K extends keyof T>
from typescript docs but I am unable to use it correctly in my example.
More specifically, the typescript complains on the line
setPersonProperty('name', (x) => x)
Although when I start typing setPersonProperty('n /* IDE autocompletes name */
but complains for the 'name'
parameter and I get the following error:
Argument of type 'string' is not assignable to parameter of type 'K'. 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string | number | symbol'.
I have also posted an image from my IDE. I am using typescript 4 . [![enter image description here][1]][1]
What am I doing wrong here ? [1]: https://i.stack.imgur.com/WzJE5.png
CodePudding user response:
I bet that this is the result You want to achieve
type Person = {
name: string,
age: number
};
export const usePerson = function <T extends Person>() {
const setPersonProperty = <K extends keyof T> (property: K, setter: (value: T[K]) => T[K]): void => {
console.log(property, setter)
}
setPersonProperty("name", (x) => x)
return setPersonProperty;
}
const setPerson = usePerson<Person>()
setPerson("name", (name) => name)
Basically, in code you provided there are two generic types when calling this usePerson hook T
and K
(<T extends Person, K extends keyof T>
).
Let's say someone will call this function with usePerson<Person, "age">()
.
What typescript will do it will replace types inside our usePerson
to be T = Person
and K = "age"
And now you have a mismatch since setPersonProperty
have first argument of type K ("age") the argument "name" is not assignable - that the error you see.