typescript - 合并 TypeScript 中对象元组的值类型

标签 typescript generics typing

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

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]]但它失败了,可能是由于 T 的索引可能存在差异和keyof T .

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

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

并指定f的返回类型如PropertyOf<T[number]> 。但还是不行。

尽管PropertyOf预期返回1 | 2对于 PropertyOf<{ a1 : 1, a2 : 2 }> ,当用作 PropertyOf<T[number]> 时在f函数返回类型为never .

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

最佳答案

您可以使用这种方法:

declare function f<T extends object[]>(
    ...t: T
): { [I in keyof T]: T[I][keyof T[I]] }[number]
  • 请注意object对于来电者来说通常比​​ { [key : string] : any } 更宽容因为后者的索引签名阻止您传入 interface 的值类型;请参阅ms/TS#15300 .

  • 请注意您的输入类型 [...{ [i in keyof T] : T[i] }]T 没有区别用于休息参数。

但重要的是,我们是mapping over the T tuple type并计算你的 PropertyOf<T>为每个元组元素键入(根据 Is there a `valueof` similar to `keyof` in TypeScript? 也称为 ValueOf<T> ),然后 indexing into生成的元组 number ,结果是 union该元组中的所有类型。

让我们测试一下:

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

const ret = f(a, b);
// const ret: 1 | 2 | "1" | "2"

看起来不错。

Playground link to code

关于typescript - 合并 TypeScript 中对象元组的值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73040062/

相关文章:

javascript - Monaco Editor 在空行上显示字符

javascript - 如何为此 Firebase 响应 JSON 构建 Typescript 接口(interface)?

node.js - 在 tsconfig.json 中指定最小/最大 `tsc` 版本

Java 泛型编译错误 - 不明白该错误

java - 如果其中一个边界是一个类,则必须首先在 java 泛型中指定它。为什么?

java - 需要对这种通用类型进行简要描述

python - 获取列表类型的元素类型

typescript - 我怎样才能在 typescript 中声明一个全局变量

generics - 如何在 Typescript 中为箭头函数创建泛型类型

javascript - 我应该尝试在 JavaScript 类中强制执行强数据类型吗?