【问题标题】:How could I have the right type?我怎么能有正确的类型?
【发布时间】:2019-10-02 18:58:34
【问题描述】:

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

我想创建一个 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 any)。

那我怎么能对 TS 说 obj[key] 作为 typeof 的值呢?

【问题讨论】:

    标签: typescript typescript-typings typescript-generics


    【解决方案1】:

    打开--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 Tkey,因此U 参数应该在该返回的函数上。如果您将&lt;T, U&gt; 放在第一个函数上,那么编译器将尝试从传递给setIem() 的值中推断出U,但它无法做到。它最终会扩大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

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

    【讨论】:

    • 很酷的东西,谢谢!起初我收到了 ok 的值:T[U],但是在将声明的 U 放在右侧之后,编译器抛出了一个错误!
    • 你是说你还有错误吗?还是一切都好?
    • 我的意思是,这是一件好事,我有错误类型的错误:D。所以你的解决方案解决了我的问题。 :)
    猜你喜欢
    • 2014-08-26
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多