对不起,标题,真的不知道适合这个问题的名字。
我想创建一个setItem函数,该函数将对象中的键设置为值:
const setItem = <T, U extends keyof T>(obj: T) => (key: U, value): void => {
obj[key] = value
}
const person = {
name: 'James',
age: 13,
}
const setPerson = setItem(person)
setPerson('name', 125)
即使我们将name属性设置为数字,也不会出现编译时错误。 (因为现在的值是typeof任何值)。
那我怎么对TS说以obj [key]作为typeof值?
答案 0 :(得分:3)
打开--strict
编译器模式,以便value
发出“隐式any
”警告。 value
的类型应为T[U]
,lookup type。
请注意,如果要使咖喱通用函数正常工作,则需要将类型参数放在正确的位置:
const setItem = <T>(obj: T) => <U extends keyof T>(key: U, value: T[U]): void => {
obj[key] = value;
}
您希望setItem(obj)
返回一个可以接受U extends keyof T
的任何key
的泛型函数,因此U
参数应该位于该返回的函数上。如果将<T, U>
放在第一个函数上,则编译器将尝试从传递给U
的值中推断setIem()
,但将无法这样做。最终将U
扩展到keyof T
,这将无法防止错误。
让我们确保此处的版本有效:
const person = {
name: 'James',
age: 13,
}
const setPerson = setItem(person)
setPerson('name', 10); // error
setPerson('name', 'Jill'); // okay
setPerson('age', 10); // okay
setPerson('age', 'Jill'); // error
希望有所帮助;祝你好运!