Проблема полягає в тому, що вбудований клас Javascript Errorрозриває ланцюжок прототипів, перемикаючи об’єкт, що будується (тобто this), на новий, інший об’єкт, коли ви телефонуєте, 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) {
super(message);
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були б порушені, наприклад, екземпляри a class VeryCustomError < CustomErrorне були б такими, instanceof VeryCustomErrorяк очікувалося, а лишеinstanceof CustomError .
Дивіться також: https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200