如何获取this对象的子类?TypeScript中safeCall方法实现求助
问题解答
一、修复TypeScript中safeCall扩展方法的类型问题
你的safeCall方法主要有两个问题:一是typeof this的写法不符合TypeScript语法规范,二是使用箭头函数会导致this指向错误(箭头函数的this是词法作用域绑定,不会指向调用该方法的对象)。下面是完整的修复方案:
1. 正确定义接口与实现
我们需要利用TypeScript的this类型,让函数参数正确接收当前对象的类型,同时改用普通函数来保留调用时的this上下文:
// 扩展Object接口,添加safeCall方法的类型定义 interface Object { safeCall<T>(this: this, func: (obj: this) => T | null | undefined): T | null; } // 实现safeCall方法,使用普通函数而非箭头函数 Object.prototype.safeCall = function<T>(func: (obj: typeof this) => T | null | undefined): T | null { try { const value = func(this); // 使用空值合并运算符,统一处理undefined和null的情况 return value ?? null; } catch { return null; } };
2. 安全获取measureUnit.id的示例
假设你的fetch请求返回的是Product类型(或包含Product的Promise),可以这样使用safeCall来安全嵌套取值:
interface MeasureUnit { id: number; title: string; } interface Product { id: number; title: string; measureUnit: MeasureUnit | null; } // 假设fetch返回Promise<Product>,需先await获取实例 const product = await fetch('....some request').then(res => res.json() as Product); // 使用safeCall安全获取measureUnit的id const measureUnitID = product.safeCall(p => p.measureUnit?.id); // 如果measureUnit为null或访问出错,measureUnitID会是null;否则返回对应的id数值
这里p => p.measureUnit?.id利用可选链操作符?.提前处理measureUnit为null的情况,再结合safeCall捕获可能的异常,实现完全安全的取值。
二、获取当前this对象的子类
在JavaScript/TypeScript中,你可以通过this.constructor来获取当前对象所属的构造函数(如果是子类实例,会直接返回子类构造函数)。
1. 获取直接子类构造函数
class BaseClass { getCurrentSubclass() { return this.constructor; } } class SubClass extends BaseClass {} const subInstance = new SubClass(); console.log(subInstance.getCurrentSubclass() === SubClass); // 输出true
2. 获取继承链上的所有子类
如果你需要遍历整个继承链获取所有父类/子类,可以通过Object.getPrototypeOf来实现:
function getAllInheritanceChain(obj: any): Function[] { const chain = []; let currentConstructor = obj.constructor; // 遍历直到顶层Object构造函数 while (currentConstructor !== Object) { chain.push(currentConstructor); // 获取当前构造函数的原型的原型对应的构造函数 currentConstructor = Object.getPrototypeOf(currentConstructor.prototype).constructor; } return chain; } // 测试 class Grandparent {} class Parent extends Grandparent {} class Child extends Parent {} const child = new Child(); console.log(getAllInheritanceChain(child)); // [Child, Parent, Grandparent]
需要注意的是,如果构造函数的prototype被手动修改过,这个方法可能会出现偏差,不过在常规的继承场景下是可靠的。
内容的提问来源于stack exchange,提问作者Bergutov Ruslan
相关产品推荐
相关产品推荐

