TypeScript函数双泛型T1 extends T2约束失效问题求解
问题根因
你写的泛型约束没有生效,是因为TypeScript的泛型推导逻辑会优先尝试找到满足所有约束的兼容类型组合,而不是直接使用你传入的第一个回调的参数类型作为T1的实际类型。在你写的反例调用中,TS会自动把T1推导为和T2相同的{a: number}类型,天然满足T1 extends T2的约束,因此不会触发编译报错。
解决方案
可以借助NoInfer工具类型标记T1的推导来源,强制TS只从第一个回调的参数位置推导T1类型,禁止它通过T2的类型反向推导收窄T1:
// TS 5.4及以上版本可直接使用内置的NoInfer function f<T1 extends T2, T2>( a: (input: NoInfer<T1>) => number, b: (input: T2) => number ) {} // 低于5.4的TS版本可以手动实现NoInfer type NoInfer<T> = [T][T extends any ? 0 : never]; function f<T1 extends T2, T2>( a: (input: NoInfer<T1>) => number, b: (input: T2) => number ) {}
效果验证
- 合法调用可正常编译:
// T1推导为{a: number, b: number},T2推导为{a: number},满足T1 extends T2,编译通过 f((input: {a: number, b: number}) => 2, (input: {a: number}) => 4); - 非法调用会触发报错:
// T1推导为{},T2推导为{a: number},{}不满足extends {a: number}的约束,编译失败 f((input: {}) => 2, (input: {a: number}) => 4);
内容的提问来源于stack exchange,提问作者Zhani Baramidze
相关产品推荐
相关产品推荐

