TypeScript中能否约束自动推断的泛型类型?
TypeScript 泛型多参数推断冲突解决方案
核心实现思路是将第二个参数标记为非泛型推断位点,禁止TS从该参数推导泛型类型,仅从第一个参数推导Prefix类型后对第二个参数做校验。
最终实现代码
type A<Keys extends string, Prefix extends string> = {[K in Keys]: `${Prefix}-${K}`} function good<K extends string, Prefix extends string>( obj: A<K, Prefix>, // 用NoInfer包裹,禁止从当前参数推断Prefix类型 prefix: NoInfer<Prefix> ) { // 业务逻辑 } const test: A<'one' | 'two', 'prefix'> = {"one": 'prefix-one', "two": 'prefix-two'} // 符合预期的调用 good(test, 'prefix') // 不符合类型约束会直接报错:类型“"other string"”的参数不能赋给类型“"prefix"”的参数 good(test, 'other string')
低版本TS兼容
如果使用的是TS 5.4以下版本(无内置NoInfer),可以手动实现NoInfer工具类型:
// 兼容TS 4.7+的写法 type NoInfer<T> = T extends infer U ? U : never // 更老版本兼容写法 // type NoInfer<T> = [T][T extends any ? 0 : never]
实现原理
- 默认情况下TS会从所有使用了泛型参数的入参位置收集推断信息,多个位置的推断结果会合并,类型不匹配时会自动拓宽为联合类型,导致约束失效
NoInfer修饰的类型位置会被TS识别为非推断位点,不会参与泛型的推导过程,仅作为校验位匹配已经从其他位点推断完成的泛型类型- 改造后
Prefix泛型仅从第一个入参obj的类型推导,第二个参数只能严格匹配推导结果,无需手动声明泛型即可达到约束效果
内容的提问来源于stack exchange,提问作者HelloWorld
相关产品推荐
相关产品推荐

