能否在TypeScript类型推断中排除this类型?
问题分析
你遇到的类型错误根源在于:类箭头函数里的this是多态this类型(它代表当前类或其子类的实例),调用getAllParents时TypeScript会把泛型T推断为这个this类型,但x => this.parent返回的是Category类型,和this类型(子类)不兼容,所以抛出“Type 'Category' is not assignable to type 'this'”的错误。
解决方案
不需要手动指定泛型或类型断言,只需调整getParent的逻辑就能解决:
1. 替换this.parent为x.parent(最简方案)
把箭头函数里的this.parent改成x.parent,让TypeScript自动推断T为Category而非this类型:
class Category { parent: Category; parentsFixed = () => { // 用x.parent替代this.parent,类型自动匹配 return getAllParents(this, x => x.parent); } }
修改后,getParent的参数x类型为Category,返回值x.parent也是Category,和泛型T完全匹配,不会再报错。
2. 让parent属性使用多态this类型(推荐支持子类场景)
如果Category需要被继承,希望子类的parent也是子类类型,可以把parent的类型改成this,泛型会自动适配子类的this类型:
class Category { parent: this; // 使用this类型,子类继承后parent会是子类类型 parentsFixed = () => { return getAllParents(this, x => x.parent); } }
这种方式能保证树形结构的类型一致性,子类调用parentsFixed时返回的父节点数组类型也会是子类类型。
3. 调整泛型函数的类型约束(适配固定父类型场景)
如果parent必须是Category类型(不能改为this),可以修改getAllParents的泛型,允许getParent返回基类类型:
// 调整泛型,兼容父节点为基类的情况 function getAllParents<T>(obj: T, getParent: (x: T) => T | null) { let result: (T | null)[] = []; let parent = getParent(obj); while (parent != null) { result.push(parent); parent = getParent(parent); } return result.filter(Boolean) as T[]; } class Category { parent: Category; parentsFixed = () => { // 用类型断言让T推断为Category return getAllParents(this as Category, x => x.parent); } }
内容的提问来源于stack exchange,提问作者Dirk Boer
相关产品推荐
相关产品推荐

