问题是 Javascript 的内置类Error
通过将要构造的对象(即this
)切换到一个新的不同对象来破坏原型链,当您调用时super
,该新对象没有预期的原型链,即它是一个实例的Error
不是CustomError
。
这个问题可以使用从 Typescript 2.2 开始支持的“new.target”优雅地解决,请参见此处:https ://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html
class CustomError extends Error {
constructor(message?: string) {
// 'Error' breaks prototype chain here
super(message);
// restore prototype chain
const actualProto = new.target.prototype;
if (Object.setPrototypeOf) { Object.setPrototypeOf(this, actualProto); }
else { this.__proto__ = actualProto; }
}
}
Usingnew.target
的优点是您不必对原型进行硬编码,就像这里提出的其他一些答案一样。这再次具有优势,继承自的类CustomError
也将自动获得正确的原型链。
如果您要对原型进行硬编码(例如Object.setPrototype(this, CustomError.prototype)
),CustomError
它本身将有一个工作原型链,但是任何继承自的类CustomError
都会被破坏,例如 a 的实例class VeryCustomError < CustomError
不会instanceof VeryCustomError
像预期的那样,而只是instanceof CustomError
.
另见:https : //github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200