能否使用mappend/条件类型扩展并转换判别式联合类型?
Absolutely! You can pull off this transformation using TypeScript conditional types—this is essentially the type-level equivalent of a "mappend" operation for your discriminated union. Let's build the DUTransformer type step by step to get exactly the result you want.
Step 1: Restate your original discriminated union
First, let's lay out your base type for clarity:
type MyDU = | { kind: 'foo' } | { kind: 'bar' };
Step 2: Define the DUTransformer type
We'll leverage distributed conditional types (a TypeScript feature where conditional types automatically apply to each member of a union) to extend each union member with the matching boolean property:
type DUTransformer<T extends { kind: string }> = T extends infer U ? U & Record<U['kind'], boolean> : never;
Step 3: Check the transformed result
When we apply this transformer to MyDU, we get exactly the union you're targeting:
type Transformed = DUTransformer<MyDU>; // This resolves to: // type Transformed = // | { kind: 'foo'; foo: boolean } // | { kind: 'bar'; bar: boolean }
How this works under the hood
Let's break down the logic for each union member:
- The conditional
T extends infer Utriggers TypeScript's distributed behavior, splittingMyDUinto its individual parts ({ kind: 'foo' }and{ kind: 'bar' }). - For each member
U,U['kind']extracts the literal string value from thekindproperty (either'foo'or'bar'). Record<U['kind'], boolean>creates a new type with a single property matching that literal string, typed asboolean(e.g.,{ foo: boolean }).- The
&operator merges the original union member with this new property type, creating the extended object type. - Finally, TypeScript automatically recombines these extended types back into a single discriminated union.
If you want to make the transformer more flexible (e.g., support kind values that are numbers or symbols), you can adjust the constraint to T extends { kind: PropertyKey } instead of string.
内容的提问来源于stack exchange,提问作者robkuz

