具有特定键和值的通用类型

Posted

技术标签:

【中文标题】具有特定键和值的通用类型【英文标题】:Generic type with specific key and value 【发布时间】:2020-06-28 21:01:10 【问题描述】:

我正在研究接受两个泛型类型参数的函数。其中之一是Object 类型,另一个是扩展keyof 传递对象类型的字符串。我需要以某种方式确定提供的Object 必须包含第二个参数中提供的键,并且它的值也应该是指定的类型。

我尝试过这样的事情:

const someFn = <
  T extends [key: string]: number | null,
  K extends keyof T
>(data: T[], dataField: K) => 

  // expecting data values to be (number | null)[] for further purposes
  const dataValues = data.map(datum => datum[dataField]);


然而,上面的代码只有在传递的对象中的所有键都是number | null时才有效

type WorkingType =  value: number | null 
const workingArray = [value: 1, value: null]

someFn<WorkingType, "value">(workingArray, "value") // this works just fine

但是如果对象包含不同类型的字段我得到错误:

type FailingType =  value: number | null, sthElse: string 
const workingArray = [value: 1, sthElse: "", value: null, sthElse]

//. Property 'sthElse' is incompatible with index signature.
//   Type 'string' is not assignable to type 'number | null'
someFn<FailingType, "value">(workingArray, "value") 

所以我需要做的是以某种方式提供信息,即只有作为K 提供的密钥需要是number | null 我尝试了类似的方法:

const someFn<
  T extends  [key: T]: number | null ,
  K extends keyof T
>(data: T[], dataKey: K) => /* ... */

但这似乎是 TS 不允许的,我得到了An index signature parameter type must be either 'string' or 'number'。有没有可能达到我的目标的方法?

【问题讨论】:

【参考方案1】:

我希望我明白你的意思,无论如何这对我有用:

    interface someFnI 
    <T,K extends keyof T>(data: T[], dataField: K);




const someFn = <
    T,
    K extends keyof T
>(data: T[], dataField: K) => 

    // expecting data values to be (number | null)[] for further purposes
const dataValues: T[K][] = data.map(datum => 
    return datum[dataField]);
    console.log(dataValues);



let myIdentity: someFnI = someFn;


type NotFailingType =  value: number | null, sthElse: string 
const workingArray = [
     value: 1, sthElse: "" , 
     value: null, sthElse: null ,
    //this will break as expected : uncomment below to check
    //  value: "notallowed", sthElse: null 
]

//. Property 'sthElse' is incompatible with index signature.
//   Type 'string' is not assignable to type 'number | null'
myIdentity<NotFailingType, "value">(workingArray, "value")



type WorkingType =  value: number | null 
const workingArray2 = [ value: 1 ,  value: null ]

myIdentity<WorkingType, "value">(workingArray2, "value")

【讨论】:

您好,感谢您的回答。不幸的是。这个解决方案不起作用,因为打字稿在这里没有推断出 dataValues(number | null)[] 类型并在我尝试使用它时抛出错误。 我编辑了我的答案,并明确了数据值的类型(泛型)。 const dataValues: T[K][] ,但我没有得到你得到错误的地方,使用你的问题中的数据我没有得到任何错误。实际上 datavalues 是 (number | null)[]

以上是关于具有特定键和值的通用类型的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 将具有相同类型的字典分组到具有完整键和值的数组中

vbscript 具有键和值的组合框

将通用JS集合转换为具有特定键和分组值的对象

如何使用 Swifty 动态创建具有多个键和值的 json 对象

如何使用php更新mongodb中具有键和值的子文档

如何使用php更新mongodb中具有键和值的子文档