【问题标题】:How to select a key from a discriminated union type?如何从可区分的联合类型中选择一个键?
【发布时间】:2023-01-13 18:48:38
【问题描述】:

我有一个受歧视的工会

type MyDUnion = { type: "anon"; name: string } | { type: "google"; idToken: string };

我想直接从 MyDUnion 类型的判别联合访问名称键。像这样的东西

type Name = MyDUnion['name']

但是打字稿不允许这样做

Property 'name' doesn't exist on type '{ type: "anon"; name: string } | { type: "google"; idToken: string }'

我怎样才能访问它?

需要明确的是,这是不是一个有效的解决方案:

type MyName = string;
type MyDUnion = { type: "anon"; name: MyName } | { type: "google"; idToken: string };
type Name = MyName; // this line would be in a different file

这是无效的,因为那时我将不得不导出 MyNameMyDUnion 类型以在其他地方使用。

有任何想法吗?

【问题讨论】:

    标签: javascript typescript discriminated-union


    【解决方案1】:

    为了获得所需的密钥,您必须以某种方式告诉 Typescript 编译器

    嘿编译器,我想知道这个对象,在一个非常具体的情况下

    在本例中,您想了解有关对象的信息,即type ==='anon'。所以,以你的例子,

    type MyDUnion = { type: "anon"; name: string } | { type: "google"; idToken: string };
    
    type SpclCase = MyDUnion & {type: "anon"}
    

    通过这样做,您将获得有关这两种情况何时重叠的信息。现在您可以直接索引 name 键。

    type Name = SpclCase['name']
    

    如果你想让它更健壮,我们可以确保我们使用的缩小类型(在本例中为{type: 'anon'})满足所需的形状。这是一个临时的解决方案。

    type DiscriminatorObj = { type: 'anon' }
    type RequiredCase = DiscriminatorObj extends Pick<MyDUnion, "type"> ? DiscriminatorObj: never;
    type SpclCase = (RequestBody & RequiredCase);
    type Name = SpclCase['name']
    

    我知道它的边缘有点粗糙,但你总是可以将它提取到通用函数中并随意使用它们。我只是向你展示了基本逻辑。您可以使用它使它更美观。

    【讨论】:

      猜你喜欢
      • 2019-02-27
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 2017-05-06
      • 2020-01-25
      • 2021-06-07
      相关资源
      最近更新 更多