我试图抛出一个自定义错误,并在控制台中打印我的“CustomError”类名而不是“Error”,但没有成功:
class CustomError extends Error { constructor(message: string) { super(`Lorem "${message}" ipsum dolor.`); this.name = 'CustomError'; } } throw new CustomError('foo');
输出是 Uncaught Error: Load "foo" very pain
.
我所期望的:Uncaught CustomError:Lorem“foo”ipsum dolor
。
我想知道是否可以仅使用 TS 来完成(而不弄乱 JS 原型)?
P粉6595169062023-10-17 19:52:38
问题在于,当您调用 super
并且该新对象没有预期的原型链,即它是 Error
的实例,而不是 CustomError
的实例。
这个问题可以使用'new.target'来优雅地解决,从 Typescript 2.2 开始就支持它,请参见这里: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; } } }
使用 new.target
的优点是您不必对原型进行硬编码,就像这里提出的其他一些答案一样。这又具有一个优点,即从 CustomError
继承的类也将自动获得正确的原型链。
如果您要对原型进行硬编码(例如 Object.setPrototype(this, CustomError.prototype)
),CustomError
本身将有一个工作原型链,但任何类从 CustomError
继承将会被破坏,例如class VeryCustomError < CustomError< CustomError
的实例不会是预期的 instanceof VeryCustomError
,而只是 instanceof CustomError
。
另请参阅:https://github.com/Microsoft/TypeScript/issues /13965#issuecomment-278570200
P粉9498488492023-10-17 16:00:03
您是否使用 typescript 版本 2.1,并转换为 ES5?检查重大更改页面的此部分以了解可能的问题和解决方法:https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built -ins-like-error-array-and-map-may-no-longer-work
相关位: