TypeScript函数返回类型被推导为参数字面量而非通用类型如何解决
解决方案
你遇到的是TypeScript默认对字面量参数做类型收窄的特性,直接用下面的代码修改即可实现预期效果:
首先定义一个类型工具用来把字面量类型拓宽为对应的通用原始类型,再修改函数返回值类型即可:
// 字面量类型拓宽工具 type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends readonly (infer V)[] ? V[] : T; // 修改后的函数 const ifNotEmpty = <U>(value: any, defaultValue: U): Widen<U> => { return value ?? defaultValue; };
效果验证
修改后调用的类型推导结果完全符合预期:
const a = ifNotEmpty(var1, "hello"); // a的类型为 string const b = ifNotEmpty(var2, [1, 2]); // b的类型为 number[] const c = ifNotEmpty(var3, true); // c的类型为 boolean const d = ifNotEmpty(var4, 123); // d的类型为 number
原理说明
TypeScript默认会对传入函数的常量字面量参数做自动类型收窄,将其推导为精度更高的字面量类型而非通用原始类型,以实现更严格的类型校验。上述方案中的Widen工具类型会自动匹配输入的字面量类型,返回对应的通用类型,从而达到你需要的推导效果。
如果你不想新增工具类型,也可以在传参时手动标注类型,写法如下:
const a = ifNotEmpty(var1, "hello" as string); const b = ifNotEmpty(var2, [1, 2] as number[]);
内容的提问来源于stack exchange,提问作者Chique
相关产品推荐
相关产品推荐

