【问题标题】:Merge value types of tuple of objects in TypeScript在 TypeScript 中合并对象元组的值类型
【发布时间】:2022-07-20 00:01:15
【问题描述】:

我有一组对象,每个对象都有自己的属性:

const a = { a1 : 1, a2 : 2 } as const
const b = { b1 : `1`, b2 : `2` } as const

函数f 将所有这些对象作为类型化元组:

function f<
    T extends { [key : string] : any }[]
> (
    ...t : [...{ [i in keyof T] : T[i] }]
) {
    // todo
}

f(a, b)

目标是返回任何这些对象的任何属性。 在这种情况下,预期的结果应该是1 | 2 | "1" | "2"

问题是我不知道如何正确描述返回类型。

我尝试过T[number][keyof T[number]],但失败了,可能是因为Tkeyof T 的索引可能存在差异。

然后我为它写了一个包装器:

type PropertyOf<T extends { [key : string] : any }> = T[keyof T]

并将f的返回类型指定为PropertyOf&lt;T[number]&gt;。但是还是不行。

尽管PropertyOfPropertyOf&lt;{ a1 : 1, a2 : 2 }&gt; 返回预期的1 | 2,但当在f 中用作PropertyOf&lt;T[number]&gt; 时,函数返回类型为never

这是什么原因以及如何解决这个问题? 谢谢。

【问题讨论】:

    标签: typescript generics typing


    【解决方案1】:

    我们可以使用以下作为f的返回类型。

    function f<
        T extends { [key : string] : any }[]
    > (...t : [...{ [i in keyof T] : T[i] }])
      : T[number] extends Record<string, infer U> ? U : never 
    {
       return {} as any
    }
    
    const result = f(a, b)
    //    ^? const result: 1 | 2 | "1" | "2"
    

    Playground


    keyof 运算符在此处不起作用,因为它仅在用于对象联合时返回共享属性。两个对象不共享任何属性,因此keyof 的计算结果为never

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2021-10-24
      • 2020-10-28
      • 2020-05-03
      • 2022-06-11
      • 2020-07-31
      • 2021-11-04
      相关资源
      最近更新 更多