【问题标题】:generic function with parameter of type T and K, where K is keyof T and an array?具有 T 和 K 类型参数的泛型函数,其中 K 是 T 的 keyof 和一个数组?
【发布时间】:2019-03-21 02:56:39
【问题描述】:

在 typescript 中,可以声明一个函数,该函数需要一个类型及其一个键作为参数:

function foo<T, K extends keyof T>(object: T, key: K)

在函数体中,您可以获取或设置object 的键值,甚至提取键的类型(T[k]):

function setter<T, K extends keyof T>(object: T, key: K){
  return (value: T[K]) => {
    obj[key] = value;
  };      
}

function logger<T, K extends keyof T>(object: T, key: K){
  console.log(obj[key]);   
}

问题:

是否可以有泛型类型Kextends keyof T 并且是一个数组? (换句话说:K 必须是数组和T 类型的键)

示例用例:

function lengthLogger<T, K /*extends keyof T and is array*/>(object: T, key: K){
  console.log(object[key].length)     
}

【问题讨论】:

    标签: function typescript generics


    【解决方案1】:

    有几种方法可以做到这一点。最好的方法是将T 声明为Kany[] 的记录

    function lengthLogger<T extends Record<K, any[]>, K extends keyof T>(object: T, key: K) {
        console.log(object[key].length)
    }
    
    lengthLogger({
        foo: "",
        bar: ["", ""]
    }, 'bar')
    
    lengthLogger({
        foo: "",
        bar: ["", ""]
    }, 'foo') // Error
    

    这提供了调用站点和声明类型的安全性。

    您会发现另一个选项是使用条件类型在K 中仅提取特定类型的属性。这适用于调用站点,但您需要声明的类型断言:

    type ExtractKeysOfType<T, TValue> = { [P in keyof T]: T[P] extends TValue ? P : TValue}[keyof T]
    function lengthLogger<T , K extends ExtractKeysOfType<T, any[]>>(object: T, key: K) {
        console.log((object as any)[key].length)
    }
    
    lengthLogger({
        foo: "",
        bar: ["", ""]
    }, 'bar')
    
    lengthLogger({
        foo: "",
        bar: ["", ""]
    }, 'foo') // Error
    

    【讨论】:

    • @Truntle 在大多数情况下它是更好的一个
    猜你喜欢
    • 1970-01-01
    • 2019-02-02
    • 2019-01-08
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多