【问题标题】:Create an array type containing all distinct keys of provided type创建一个包含所提供类型的所有不同键的数组类型
【发布时间】:2021-07-02 11:14:29
【问题描述】:

我想创建一个泛型类型,比如说

type KeyArr<T>

这将包含T 的键排列的联合

例如:

type foo = KeyArr<{a:1, b:2}>;

应该和

一样
type foo = ['a', 'b'] | ['b', 'a'];

这可以实现吗?

【问题讨论】:

  • 有一个相当干净的解决方案,它可以为您提供所有排列的联合,即['a', 'b'] | ['b', 'a'] 而不仅仅是['a', 'b'],因为属性没有按类型排序,所以这是有道理的。如果你对此感兴趣,我可以写出来。
  • 如果不是太麻烦,我绝对会喜欢它
  • 这是一个相当晚的反应!但事实证明,我的浏览器历史中仍然存在这个问题:tsplay.dev/NVnDqN
  • 这太棒了!正是我想要的。请发布此问题的答案,以便我确认!

标签: typescript typescript-typings typescript-generics


【解决方案1】:

计算所有排列元组的并集实际上比将一个并集转换为单个元组要简单一些。具有条件的递归映射类型在空对象上返回 [] 而不是 never,将完成这项工作:

type KeyArr<T> =
  keyof T extends []
  ? []
  : {[K in keyof T]: [K, ...KeyArr<Omit<T,K>>]}[keyof T]

type Foo1 = KeyArr<{}>               // []
type Foo2 = KeyArr<{a:1, b:2}>       // ["a", "b"] | ["b", "a"]
type Foo3 = KeyArr<{a:1, b:2, c: 3}> // ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"] | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]

TypeScript playground

不过,联合类型很快就会变得非常大。对于具有 8 个属性的对象,联合有 40320 个成员,TypeScript 明显变慢,而对于 9 个属性(这将创建一个 362880 的联合),它完全失败。

【讨论】:

    【解决方案2】:

    一般 - 是的,这是可能的。如果在您的情况下拥有一个接受来自 object 的每个键的 Array 类型就足够了,请查看下面的代码。如果您需要 Tuple 类型,它会更复杂,看看这个thread

    type KeyArr<T extends object> = Array<keyof T>
    

    【讨论】:

    • 你提供的链接正是我要找的
    【解决方案3】:
    type KeyArr<T> = Array<keyof T>;
    

    注意这种类型允许数组中的键重复。

    【讨论】:

    • 我需要它只包含每个键一次。这可能吗?
    猜你喜欢
    • 2011-11-30
    • 2020-10-16
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2019-12-03
    相关资源
    最近更新 更多