Typescript泛型继承接口时自定义复杂Paths类型无法识别问题
问题原因
- 泛型约束
T extends Person仅要求T是Person的子类型,允许T扩展额外属性、修改原有属性的嵌套结构,不等于T和Person结构完全一致。 Paths是自定义递归条件类型,TS对未绑定具体值的泛型参数,不会提前展开计算依赖该泛型的条件类型结果,也不会主动基于泛型约束推导自定义条件类型的子类型关系。此时Paths<T>会被视为不透明的黑盒类型,TS无法判定'name'属于该类型的合法取值。- 原生的
keyof操作符有内置的协变推断规则,只要T extends Person,TS就可以确定keyof T一定包含keyof Person的所有成员,因此'name'可以直接赋值给keyof T。
解决方案
根据你的使用场景可以选择两种处理方式:
确定赋值路径一定存在于所有符合约束的T中
直接用类型断言告知TS该值合法即可:
function foo<T extends Person>() { let personParamBad: Paths<T> personParamBad = 'name' as Paths<T> }
需要TS自动校验路径合法性
可以将变量类型定义为Paths<Person>和Paths<T>的交叉类型,既保证赋值的路径是Person的合法路径,又兼容泛型T的扩展特性:
function foo<T extends Person>() { let personParamBad: Paths<Person> & Paths<T> personParamBad = 'name' // 正常通过校验 personParamBad = 'invalid' // 会抛出类型错误 }
如果不需要用到T的扩展路径,也可以直接将变量类型写为Paths<Person>,从根源避免该问题。
内容的提问来源于stack exchange,提问作者TG Person
相关产品推荐
相关产品推荐

