【问题标题】:Difference between of "K extends keyof T" vs. directly using "keyof T"?“K extends keyof T”与直接使用“keyof T”的区别?
【发布时间】:2021-11-29 13:29:06
【问题描述】:

以下打字稿定义有什么区别:

function prop<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

function prop2<T>(obj: T, key: keyof T) {
    return obj[key];
}

我的意思是不,但也许我监督了一些事情。使用第一个版本(在文档中经常使用)有什么好处

【问题讨论】:

    标签: typescript


    【解决方案1】:

    不同之处在于,在第一种情况下,返回类型为T[K],而在第二种情况下,返回类型为T[keyof T]K 可以是最广泛的 keyof T 但它可以是表示键的特定字符串文字类型。这意味着如果K 是特定属性,则返回值将与该属性的类型相同:

    function prop<T, K extends keyof T>(obj: T, key: K) {
        return obj[key];
    }
    function prop2<T>(obj: T, key: keyof T) {
        return obj[key];
    }
    
    let o = {
        p1: 0,
        p2: ''
    }
    
    let v = prop(o, 'p1') // is number, K is of type 'p1'
    let v2 = prop2(o, 'p1') // is number | string, no extra info is captured
    

    【讨论】:

    • 好的,我明白了。谢谢!
    • 我现在明白其中的区别了。但是prop2 所表现出的行为何时会是可取的或有用的呢?换句话说,为什么 TypeScript 作为设计决策不让 keyof T 产生 extends keyof T 所表现出的行为并消除这种混淆?
    【解决方案2】:

    这2个表达式有很大的不同,会导致编译器的行为不同。


    function prop<T, K extends keyof T>(obj: T, key: K) {
        return obj[key];
    }
    

    这有助于constraint the generic parameter 避免使用any,但也确保输入参数是T 的道具


    function prop2<T>(obj: T, key: keyof T) {
        return obj[key];
    }
    

    这不会为 getter 引发编译器错误,但会在 setter 情况下引发: Type 'any' is not assignable to type 'never'.ts(2322)

    function prop2<T>(obj: T, key: keyof T, value: any) {
        obj[key] = value;
    }
    

    原因是keyof 将导致 obj[key] 具有never 类型(键没有重叠),阅读更多https://stackoverflow.com/a/61758818/9814737

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 2017-07-25
      • 1970-01-01
      相关资源
      最近更新 更多