我怎样才能找到正确的类型?

时间:2019-05-15 15:12:16

标签: typescript typescript-typings typescript-generics

对不起,标题,真的不知道适合这个问题的名字。

我想创建一个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值?

1 个答案:

答案 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

Playground link to code

希望有所帮助;祝你好运!