You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过判别属性从联合类型中获取对应类型及实现映射?

Extracting Types from a Discriminated Union by Tag in TypeScript

Absolutely! You can absolutely pull the exact type from your discriminated union using its tag discriminant property, and TypeScript gives you clean tools to build the tag-to-type mapping you want. Let's walk through this with concrete examples.

First, let's define the union and its member types to match your scenario:

// Define the individual tagged types
interface Foo {
  tag: 'foo';
  fooSpecific: string;
}

interface Bar {
  tag: 'bar';
  barSpecific: number;
}

interface Baz {
  tag: 'baz';
  bazSpecific: boolean;
}

// The discriminated union
type Thing = Foo | Bar | Baz;

1. Extract a Single Type by Tag

To get the type corresponding to a specific tag value, TypeScript's built-in Extract utility type is perfect. It filters the union to only include members that match the condition you specify:

// Create a helper type that takes a tag and returns the matching type
type ThingByTag<T extends Thing['tag']> = Extract<Thing, { tag: T }>;

// Usage: Grab the exact type for any tag
type FooType = ThingByTag<'foo'>; // Resolves to Foo
type BarType = ThingByTag<'bar'>; // Resolves to Bar

How this works: Thing['tag'] gets all possible tag values from the union ('foo' | 'bar' | 'baz'), and Extract<Thing, { tag: T }> picks only the union member where the tag property equals T.

2. Build a Full Tag-to-Type Mapping

To create a complete mapping of all tags to their corresponding types (the mapping type you mentioned), you can combine the helper above with a mapped type:

// Map every tag in the union to its matching type
type ThingMap = {
  [Tag in Thing['tag']]: ThingByTag<Tag>;
};

// Now you can access types directly via their tag key
type FooFromMap = ThingMap['foo']; // Foo
type BazFromMap = ThingMap['baz']; // Baz

This mapped type iterates over every possible tag value from the union, and assigns each tag to the type you extracted with ThingByTag.

Alternative: Custom Conditional Type (Without Extract)

If you want to avoid using the built-in Extract utility, you can write a custom conditional type to achieve the same result:

type ThingByTagCustom<T extends Thing['tag']> = 
  Thing extends { tag: T } ? Thing : never;

// This works identically to the Extract version
type BarTypeCustom = ThingByTagCustom<'bar'>; // Bar

This conditional type checks each member of the union to see if its tag matches T, and returns that member if it does.

All these approaches work reliably as long as your union is properly discriminated (each member has a unique literal tag property, which you confirmed is the case here).

内容的提问来源于stack exchange,提问作者Peter Hudec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:51:51