参数类型为T和K的泛型函数,其中K是T的键和数组? [英] generic function with parameter of type T and K, where K is keyof T and an array?

查看:101
本文介绍了参数类型为T和K的泛型函数,其中K是T的键和数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在打字稿中,可以声明一个需要一个类型及其键之一作为参数的函数:

In typescript it's possbile to declare a function that expects a type and one of its keys as parameters:

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

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

In the function body you're then able to get or set the value of the object's key value and even extract the type of the key (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类型的键)

Is it possbile to have generic type K that extends keyof T and is an array? (In other words: K must be an array and a key of type T)

用例示例:

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

推荐答案

有几种方法可以做到这一点.最好的方法是将T声明为any[]

There are several ways to do this. The best one is to declare T as being a record of K of any[]

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

这可以确保呼叫站点和声明类型的安全性.

This gives both call site and declaration type safety.

您将找到的另一种选择是使用条件类型在K中仅提取特定类型的属性.这对于呼叫站点效果很好,但是您需要声明的类型断言:

Another option you will find is to use conditional types to extract in K only the properties of a specific type. This works well for the call site but you will need type assertions for the declaration:

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

这篇关于参数类型为T和K的泛型函数,其中K是T的键和数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆