从具有不同键的嵌套对象的值创建联合

Posted

技术标签:

【中文标题】从具有不同键的嵌套对象的值创建联合【英文标题】:Create a union from values of a nested object with different keys 【发布时间】:2020-07-31 12:15:17 【问题描述】:

鉴于我有以下Options 类型

interface Options 
  parent1: 
    child1: 
      foo: 'bar'
    
  ;
  parent2: 
    child2: 
      baz: 'daz'
    
  ;

在这种情况下,如何将其变成所有 2 级子属性值的并集

 foo: 'bar'  |  baz: 'daz' 

我尝试了以下

type KnownOptions = Options[keyof Options][keyof Options[keyof Options]];

但这只有在所有***属性中的第 2 级子属性都相同时才有效。例如。当我将child2 重命名为 `child1

Playground

【问题讨论】:

【参考方案1】:

您可以使用映射类型来获取嵌套类型:

type KnownOptions<T> = T extends 
  [k in keyof T]: 
    [k: string]: infer OptionValue
  
 ? OptionValue : never

// Good:
const a: KnownOptions<Options> =  foo: 'bar' 
const b: KnownOptions<Options> =  baz: 'daz' 

// Expect errors:
const c: KnownOptions<Options> =  foo: 'bad value' 
const d: KnownOptions<Options> =  badKey: 'bar' 

Playground

这是一个泛型类型,它接受具有两级键的类型。条件类型(由三元 T extends Type ? A : B 指出)表示“如果泛型类型 T 是至少 2 级深度的对象,则返回每个第二级的类型。否则,返回 never 类型,因为泛型类型无效。

infer OptionalValue 表示“无论是什么类型,都保存为OptionValue”。然后由条件类型返回,在将多个类型保存到它之后,创建每个类型的联合。

我必须承认,我不完全确定为什么第一级密钥需要是 k in keyof T 而第二级可能只是 k: string。但是,这是我让它正常工作的唯一方法。

【讨论】:

【参考方案2】:

我会这样写KnownOptions

type KnownOptions =  [K in keyof Options]: Options[K][keyof Options[K]] [keyof Options];

这里我们将mapping Options 的每个属性都连接到 its 属性的联合中,然后将所有这些联合联合在一起。如果我们按照这样定义的ValueOf&lt;T&gt; 编写它可能更有意义:

type ValueOf<T> = T[keyof T];

type KO = ValueOf< [K in keyof Options]: ValueOf<Options[K]> >;

所以ValueOf&lt;T&gt; 为您提供对象T 的属性值类型的联合(例如,ValueOf&lt;a: string, b: number&gt;string | number),所以您正在做的是将Options 的每个属性映射到@ 987654334@ 然后把ValueOf 全部拿走。

您可以根据需要验证每个定义的计算结果为 foo: "bar"; | baz: "daz";


好的,希望对您有所帮助;祝你好运!

Playground link to code

【讨论】:

【参考方案3】:

您可以使用['propName'] 表示法对类型进行索引以提取类型

type KnownOptions = Options['parent1']['child1'] | Options['parent2']['child2']

【讨论】:

以上是关于从具有不同键的嵌套对象的值创建联合的主要内容,如果未能解决你的问题,请参考以下文章

联合两个具有嵌套不同模式的数据框

创建具有不同键的哈希数组的 CSV

具有深度嵌套层次结构的不可变 NSDictionary:更改键的值?

打字稿中具有联合类型键的松散类型对象

具有相同键的(嵌套)字典的 Pythonic 替代方案?

如何使用 SQL sum 函数在不同的 MySQL 表中添加具有相应主键的值?