TypeScript中如何根据输入参数的可选属性动态定义函数返回类型?
实现方案
完全可以实现这个需求,核心是利用TypeScript的函数重载或泛型条件类型,让返回类型根据传入的参数结构动态变化。以下是具体实现:
方法一:函数重载(更直观)
先拆分参数类型,再通过重载明确不同参数对应的返回类型:
// 基础参数类型 type BaseParams = { first: string; second: number; }; // 带third的参数类型 type ParamsWithThird = BaseParams & { third: boolean }; // 函数重载定义 function functionA(params: BaseParams): never; function functionA(params: ParamsWithThird): { [key: string]: any }; // 函数实现 function functionA(params: BaseParams & { third?: boolean }) { if ('third' in params) { return { one: "object" }; } // never类型表示函数不会正常返回,这里通过抛出错误满足类型要求 throw new Error("未传入third参数,无法返回有效值"); }
方法二:泛型条件类型(自动推断)
通过泛型结合条件类型,让TypeScript根据传入的参数自动推导返回类型:
type Params = { first: string; second: number; third?: boolean; }; // 泛型函数类型,根据参数是否包含third决定返回类型 type FunctionA<T extends Params> = T extends { third: boolean } ? (params: T) => { [key: string]: any } : (params: T) => never; // 实现函数 const functionA: FunctionA<Params> = (params) => { if ('third' in params) { return { one: "object" }; } throw new Error("未传入third参数"); };
调用测试
两种方式都能得到正确的类型推断:
- 不传入
third:const res1 = functionA({ first: "test", second: 123 });→res1类型为never - 传入
third:const res2 = functionA({ first: "test", second: 123, third: true });→res2类型为{ [key: string]: any } - 传入
third: false:const res3 = functionA({ first: "test", second: 123, third: false });→res3类型同样为{ [key: string]: any }
需要注意的是,never类型表示函数不会正常返回值,所以在不传入third的分支里,必须确保函数不会通过return返回有效值(比如抛出错误、无限循环等),否则TypeScript会报错。
内容的提问来源于stack exchange,提问作者Flo Ragossnig
相关产品推荐
相关产品推荐

