TypeScript中继承Array的子类如何不依赖constructor.name获取类名
这个问题是TypeScript编译目标低于ES6时的特有表现:对于Array、Map这类内置对象的子类,TS为了兼容ES5的继承逻辑,会调整实例的原型指向,导致实例的constructor被指向父类Array,因此constructor.name返回Array而非A。
下面是不依赖constructor.name的可行方案:
方案1:添加显式类名标识(兼容性最好)
直接在类中定义固定的类名属性,不受编译配置、代码压缩的影响,是最稳定的实现:
class A extends Array { // 静态类名标识,可通过 A.className 或实例的 constructor.className 访问 public static readonly className = 'A'; // 实例级getter,可直接通过实例访问类名 public get className() { return A.className; } private _foo: string; constructor(settings: any) { super(); this._foo = 'foo'; } get Foo() { return this._foo; } set Foo(value) { this._foo = value; } } // 使用示例 let test = new A({ }); console.log(test.className); // 输出 'A' console.log(A.className); // 输出 'A'
如果存在多级继承,只需要在每个子类中覆写对应的className静态属性即可。
方案2:调整编译配置(依赖原生ES6继承逻辑)
如果你的运行环境支持ES6及以上标准,可以修改tsconfig.json中的编译目标配置:
{ "compilerOptions": { "target": "ES2015" // 或更高的ES2016/ES2020等 } }
调整后TS会使用原生ES6类继承逻辑,此时test.constructor.name也能正常返回A,但该方案依然依赖constructor.name属性,且无法兼容ES5及更低版本的运行环境。
内容的提问来源于stack exchange,提问作者CoryG
相关产品推荐
相关产品推荐

