如何获取嵌套对象的值类型的并集?

huangapple go评论62阅读模式
英文:

How to get union of value types of a nested object?

问题

以下是代码的翻译部分:

给定这样的对象:
```ts
const deepNestedObject = {
  a: "value",
  b: {
    c: "nestedvalue",
    d: {
       e: "deepNestedValue"
    }
  }
}

如何生成一个联合类型,仅限于边缘的非对象值

type EdgeValueUnion = DeepValueOf<typeof deepNestedObject>; // 应该等同于 "value" | "nestedValue" | "deepNestedValue"

到目前为止,我尝试过这个:

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

type DeepValueOf<
  T extends Record<string, unknown>,
  Key = keyof T
> = Key extends string
  ? T[Key] extends Record<string, unknown>
    ? DeepValueOf<T[Key]>
    : ValueOf<T>
  : never;

但它还不太对,因为它仍然允许树中的对象值通过。例如:

const edgeValue: EdgeValueUnion = deepNestedObject.b;

示例TS沙箱


<details>
<summary>英文:</summary>

Given an object like this:
```ts
const deepNestedObject = {
  a: &quot;value&quot;,
  b: {
    c: &quot;nestedvalue&quot;
    d: {
       e: &quot;deepNestedValue&quot;
    }
  }
}

How do I generate a union type of specifically only the non-object values at the edge

type EdgeValueUnion = DeepValueOf&lt;typeof deepNestedObject&gt;; // Should equate to &quot;value&quot; | &quot;nestedValue&quot; | &quot;deepNestedValue&quot;

So far I've tried this:

type ValueOf&lt;T&gt; = T[keyof T];

type DeepValueOf&lt;
  T extends Record&lt;string, unknown&gt;,
  Key = keyof T
&gt; = Key extends string
  ? T[Key] extends Record&lt;string, unknown&gt;
    ? DeepValueOf&lt;T[Key]&gt;
    : ValueOf&lt;T&gt;
  : never;

but it's not quite right because it still allows object values in the tree to pass. e.g.

const edgeValue: EdgeValueUnion = deepNestedObject.b;

Sample TS sandbox

答案1

得分: 1

从值中提取所有字符串:

type EdgeValueUnion = Extract<DeepValueOf<typeof deepNestedObject>, string>;

还需要使用 const 断言来确保这些字符串被推断为字面量,而不是通用的 string 类型:

const deepNestedObject = {
    a: "value",
    b: {
        c: "nestedvalue",
        d: {
            e: "deepNestedValue",
        },
    },
} as const;

Playground

英文:

Extract all the strings from the values:

type EdgeValueUnion = Extract&lt;DeepValueOf&lt;typeof deepNestedObject&gt;, string&gt;;

You also need a const assertion to make sure the strings are inferred as literals instead of the general string type:

const deepNestedObject = {
    a: &quot;value&quot;,
    b: {
        c: &quot;nestedvalue&quot;,
        d: {
            e: &quot;deepNestedValue&quot;,
        },
    },
} as const;

Playground

huangapple
  • 本文由 发表于 2023年3月4日 05:10:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定