TypeScript为何不对默认泛型类型的输入进行校验?
TypeScript默认泛型为何不触发输入校验?
问题场景
给定以下泛型函数签名:
const logIt = <T = string>(t: T) => {console.log(t)};
调用时的预期与实际表现:
logIt(1); // 期望触发编译错误(number ≠ string),但实际无错误 logIt<string>(1) // 触发错误(符合预期) logIt<number>(2) // 正常运行(符合预期)
想知道为什么默认泛型类型(string)似乎不起作用,无法对无泛型参数的调用做类型校验?
原因解析
这是因为TypeScript对泛型函数的类型推断优先级高于默认泛型:
- 当你不显式指定泛型参数时,TS会自动根据传入的参数值推导
T的类型。比如调用logIt(1)时,TS会直接把T推断为number,完全不会用到默认的string类型。 - 默认泛型的作用场景是:当TS无法从函数参数中推断出
T的类型时,才会 fallback 到默认类型。比如函数无参数,或者参数类型和T无关的情况,例如:const logEmpty = <T = string>() => { console.log("empty") }; // 此时T会被推断为默认的string
实现预期需求的方法
如果你希望不显式传泛型参数时,强制校验输入必须为string,可以通过函数重载实现:
// 重载签名1:默认情况,参数必须是string function logIt(t: string): void; // 重载签名2:显式指定泛型时,参数为对应类型 function logIt<T>(t: T): void; // 实现体 function logIt(t: unknown) { console.log(t); }
此时调用表现会符合你的预期:
logIt(1); // 触发编译错误(符合预期) logIt<string>(1) // 触发错误(符合预期) logIt<number>(2) // 正常运行(符合预期)
内容的提问来源于stack exchange,提问作者gamov
相关产品推荐
相关产品推荐

