TypeScript中关联两个泛型并通过单值检查实现类型收窄的方法
问题分析
你遇到的报错是因为当前TypeScript的类型系统暂不支持自动关联同一个泛型参数在不同位置的类型推导:当你收窄泛型参数T的取值value为A时,TS无法自动推导出另一个使用了T的参数next的类型是ComplexType<A>,因此会触发类型错误。
可行实现方案
- 方案1:直接类型断言
如果你确定你的业务逻辑完全符合value为A时next一定是ComplexType<A>的约束,最简单的方式是直接添加类型断言跳过检查:const builder = <T extends AB>(value: T) => (next: ComplexType<T>) => { if (value === 'A') { f(next as ComplexType<A>) } } - 方案2:使用可辨识联合类型重构
如果你不想用断言,可以把关联的两个值封装到同一个可辨识联合结构中,TS可以自动识别这种结构的类型收窄:// 定义可辨识联合类型,value作为辨识键 type BuilderParam = | { value: A; next: ComplexType<A> } | { value: B; next: ComplexType<B> } const builder = <T extends AB>(value: T) => (next: ComplexType<T>) => { // 把两个关联值合并为可辨识联合对象 const param = { value, next } as BuilderParam if (param.value === 'A') { f(param.next) // TS自动推导param.next为ComplexType<A>,无报错 } } - 方案3:自定义类型守卫封装判断逻辑
你也可以把关联判断逻辑封装为自定义类型守卫,让TS能识别类型收窄的规则:// 自定义类型守卫,关联value和next的类型 function isTypeA(value: AB, next: ComplexType<AB>): next is ComplexType<A> { return value === 'A' } const builder = <T extends AB>(value: T) => (next: ComplexType<T>) => { if (isTypeA(value, next)) { f(next) // 类型检查正常通过 } }
内容的提问来源于stack exchange,提问作者soe165
相关产品推荐
相关产品推荐

