如何为根据参数值返回不同类型的函数做TypeScript类型检查?
解决根据参数值动态返回类型的TypeScript函数标注问题
针对你这个需求,有两种常用且靠谱的实现方式:
1. 函数重载(最直观的方案)
函数重载可以直接为不同的参数值指定对应的返回类型,写法清晰易懂:
// 重载签名:定义不同参数对应的返回类型 function foo(arg: 'a'): { prop1: string; prop2: number }; function foo(arg: 'b'): number[]; // 实现签名:编写函数具体逻辑 function foo(arg: 'a' | 'b') { if (arg === 'a') { return { prop1: 'hello', prop2: 123 }; } else { return [1, 2, 3]; } } // 验证效果 const resA = foo('a'); resA.prop1; // TS能识别该属性,无类型报错 resA.prop2; const resB = foo('b'); resB.push(4); // 能识别为数字数组,支持数组方法
重载的核心是先定义多个重载签名(仅描述参数与返回类型,不写逻辑),最后写一个覆盖所有参数可能性的实现签名完成函数逻辑。TS会根据传入的参数自动匹配对应重载签名,推导出正确的返回类型。
2. 泛型+条件类型(更灵活的方案)
如果需要处理更复杂的参数-返回类型映射,可以用泛型结合条件类型实现:
type FooReturn<T extends 'a' | 'b'> = T extends 'a' ? { prop1: string; prop2: number } : number[]; function foo<T extends 'a' | 'b'>(arg: T): FooReturn<T> { if (arg === 'a') { return { prop1: 'hello', prop2: 123 } as FooReturn<T>; } else { return [1, 2, 3] as FooReturn<T>; } } // 验证效果 const resA = foo('a'); // 类型为{ prop1: string; prop2: number } const resB = foo('b'); // 类型为number[]
这里先定义条件类型FooReturn,根据泛型参数T的取值返回对应类型。函数接收泛型参数T,并指定返回类型为FooReturn<T>。注意需要用类型断言as FooReturn<T>,因为TS编译器在函数内部无法自动推导泛型对应的具体返回类型。
两种方案对比:
- 函数重载适合分支少、逻辑简单的场景,可读性更强;
- 泛型+条件类型适合需要批量映射类型的场景,扩展性更好。
内容的提问来源于stack exchange,提问作者Ilya Rogulin
相关产品推荐
相关产品推荐

