在 TypeScript 中,你可以使用映射类型(Mapped Types)和条件类型(Conditional Types)来从列表中提取区分的联合类型,而不需要显式地指定构造函数。以下是一个基本的例子:
type List = { type: 'a'; value: string } | { type: 'b'; value: number };
// 使用映射类型和条件类型来提取 'a' 类型的 value
type ExtractAValue<T> = T extends { type: 'a'; value: infer U } ? U : never;
// 使用 ExtractAValue 提取 List 中 'a' 类型的 value
type AValues = ExtractAValue<List>; // string
// 类似地,提取 'b' 类型的 value
type ExtractBValue<T> = T extends { type: 'b'; value: infer U } ? U : never;
type BValues = ExtractBValue<List>; // number
在这个例子中,List
是一个联合类型,包含了两种不同的对象结构。ExtractAValue
和 ExtractBValue
是两个条件类型,它们检查传入的类型 T
是否符合特定的结构,并从中提取 value
字段的类型。
优势:
应用场景:
遇到的问题及解决方法:
如果你在尝试提取联合类型中的某个字段时遇到了问题,可能是因为 TypeScript 无法正确推断出类型。这时,你可以使用 infer
关键字来帮助 TypeScript 进行类型推断。
例如,如果你尝试提取一个更复杂的联合类型中的字段,但 TypeScript 提示错误,你可以尝试细化条件类型,或者使用多个条件类型组合来达到目的。
type ComplexList = { type: 'a'; value: string } | { type: 'b'; value: number } | { type: 'c'; value: boolean };
// 提取 'a' 或 'b' 类型的 value
type ExtractABValue<T> = T extends { type: 'a' | 'b'; value: infer U } ? U : never;
type ABValues = ExtractABValue<ComplexList>; // string | number
在这个例子中,ExtractABValue
条件类型使用了 |
来指定 type
字段可以是 'a'
或 'b'
,这样就可以正确地提取这两种类型的 value
字段了。
参考链接:
infer
关键字:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#type-inference-in-conditional-types领取专属 10元无门槛券
手把手带您无忧上云