能否从判别联合类型生成字面量值组合集?可用于测试数据生成
如何处理TypeScript联合类型以获取字面量值的组合集?
当然可以实现!针对你提出的这个TypeScript联合类型场景,我们可以结合类型工具和运行时代码来生成你需要的字面量组合集,这对于测试数据生成来说确实非常实用。
实现思路
核心思路是:利用TypeScript的条件类型提取联合类型中每个成员的type和color字面量组合,同时在运行时提供对应的实例数据,通过函数映射出目标格式的组合数组。
完整代码实现
首先定义你的类型和联合类型:
interface Foo { type: 'Car'; color: 'red'; } interface Bar { type: 'Car'; color: 'blue'; } interface Baz { type: 'Bike'; color: 'yellow'; } type Union = Foo | Bar | Baz;
接下来,我们可以先定义一个类型工具,用来提取联合类型中每个成员的[type, color]元组类型(这一步是类型层面的校验,确保我们的目标组合符合类型定义):
type ExtractCombination<T> = T extends { type: infer U; color: infer V } ? [U, V] : never; // 此时 UnionCombinations 的类型就是 ['Car', 'red'] | ['Car', 'blue'] | ['Bike', 'yellow'] type UnionCombinations = ExtractCombination<Union>;
然后是运行时的函数实现。由于TypeScript类型信息在运行时会被擦除,我们需要提供联合类型对应的所有实例作为数据源,再通过函数生成目标组合:
// 提供联合类型的所有合法实例(TypeScript会自动校验这些实例是否符合Union类型) const unionDataSource: Union[] = [ { type: 'Car', color: 'red' }, { type: 'Car', color: 'blue' }, { type: 'Bike', color: 'yellow' }, ]; function getCombinations<T extends { type: string; color: string }>(data: T[]): ExtractCombination<T>[] { return data.map(item => [item.type, item.color] as ExtractCombination<T>); } // 调用函数并输出结果 console.log(getCombinations(unionDataSource)); // 输出结果完全符合你的预期: // [ // ['Car', 'red'], // ['Car', 'blue'], // ['Bike', 'yellow'], // ]
优化:确保数据源的类型安全
如果你担心手动维护unionDataSource时会遗漏或错误添加成员,可以添加一个类型守卫来做双重校验:
function isValidUnionInstance(obj: unknown): obj is Union { if (typeof obj !== 'object' || obj === null) return false; const { type, color } = obj as { type?: string; color?: string }; const validTypeColorMap = { Car: ['red', 'blue'], Bike: ['yellow'], } as const; return ( type in validTypeColorMap && validTypeColorMap[type as keyof typeof validTypeColorMap].includes(color!) ); } // 使用类型守卫过滤数据源,确保所有成员都符合Union类型 const safeDataSource = [ { type: 'Car', color: 'red' }, { type: 'Car', color: 'blue' }, { type: 'Bike', color: 'yellow' }, // { type: 'Car', color: 'green' }, // 这里会触发类型错误,编译阶段就能发现问题 ].filter(isValidUnionInstance);
适用场景说明
这种方案完全适配测试数据生成的需求:你可以基于生成的组合数组,快速扩展出完整的测试用例对象,而且全程有TypeScript的类型校验保驾护航,避免测试数据不符合类型定义的问题。
内容的提问来源于stack exchange,提问作者Ashley Coolman
相关产品推荐
相关产品推荐

