如何从联合类型中获取与extension匹配的对应params类型?
问题:根据联合类型的辨识字段获取对应参数类型
原始代码如下:
type TypeA = { someRandomStuff: { name: 'tom' } } type TypeB = { doWrite: { path: '/any/path' } } type Executions<T extends [string, {[key: string]: unknown}]> = { extension: T[0]; params: T[1]; } function executionListener(exec: Executions<['random',TypeA] | ['write',TypeB]>) { if(exec.extension === 'random') { const params = exec.params.someRandomStuff; // 类型报错:无法确定params是TypeA } }
解决方案
核心是让TypeScript能识别extension和params的关联关系,通过映射类型生成可辨识联合即可解决:
- 先定义一个映射类型,把每个
extension字符串和对应的参数类型绑定:
type ExecutionMap = { random: TypeA; write: TypeB; };
- 基于这个映射类型生成可辨识联合类型
Executions:
type Executions = { [K in keyof ExecutionMap]: { extension: K; params: ExecutionMap[K]; }; }[keyof ExecutionMap];
- 修改函数使用这个类型,此时TypeScript会自动根据
extension的判断缩小params的类型:
function executionListener(exec: Executions) { if (exec.extension === 'random') { const params = exec.params.someRandomStuff; // 正确识别为TypeA,无报错 console.log(params.name); // 可以正常访问name字段 } else { const params = exec.params.doWrite; // 自动推断为TypeB console.log(params.path); // 可以正常访问path字段 } }
原理说明
原来的泛型写法虽然最终生成的联合类型结构类似,但TypeScript无法自动关联extension和params的对应关系。而通过映射类型生成的可辨识联合,每个分支的extension是字面量类型,TypeScript会把它作为辨识符,在判断extension的值后,自动将params的类型缩小到对应分支的类型。
内容的提问来源于stack exchange,提问作者Marcel Armada-Castellon
相关产品推荐
相关产品推荐

