为什么打字稿不能正确推断 T[K] 与 <T extends Person, K extends keyof T> 泛型?
Why typescript does not properly infer T[K] with <T extends Person, K extends keyof T> generic?
我已经创建了一个 React 钩子:
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;
}
我从 typescript 文档中看到了模式 <T, K extends keyof T>
,但我无法在我的示例中正确使用它。
更具体地说,打字稿在线抱怨
setPersonProperty('name', (x) => x)
虽然当我开始输入 setPersonProperty('n /* IDE autocompletes name */
但抱怨 'name'
参数时,我收到以下错误:
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'.
我还发布了一张来自 IDE 的图片。我正在使用打字稿 4+。
[![在此处输入图片描述][1]][1]
我做错了什么?
[1]: https://i.stack.imgur.com/WzJE5.png
我打赌这就是你想要达到的结果
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)
基本上,在调用此 usePerson 挂钩时,在您提供的代码中有两种泛型类型 T
和 K
(<T extends Person, K extends keyof T>
)。
假设有人会用 usePerson<Person, "age">()
调用此函数。
打字稿会做什么,它将把 usePerson
中的类型替换为 T = Person
和 K = "age"
现在你有一个不匹配,因为 setPersonProperty
有 K 类型的第一个参数(“年龄”)参数“名称”不可分配 - 你看到的错误。
我已经创建了一个 React 钩子:
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;
}
我从 typescript 文档中看到了模式 <T, K extends keyof T>
,但我无法在我的示例中正确使用它。
更具体地说,打字稿在线抱怨
setPersonProperty('name', (x) => x)
虽然当我开始输入 setPersonProperty('n /* IDE autocompletes name */
但抱怨 'name'
参数时,我收到以下错误:
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'.
我还发布了一张来自 IDE 的图片。我正在使用打字稿 4+。 [![在此处输入图片描述][1]][1]
我做错了什么? [1]: https://i.stack.imgur.com/WzJE5.png
我打赌这就是你想要达到的结果
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)
基本上,在调用此 usePerson 挂钩时,在您提供的代码中有两种泛型类型 T
和 K
(<T extends Person, K extends keyof T>
)。
假设有人会用 usePerson<Person, "age">()
调用此函数。
打字稿会做什么,它将把 usePerson
中的类型替换为 T = Person
和 K = "age"
现在你有一个不匹配,因为 setPersonProperty
有 K 类型的第一个参数(“年龄”)参数“名称”不可分配 - 你看到的错误。