Le problème est que la classe intégrée de Javascript Error
rompt la chaîne du prototype en changeant l'objet à construire (c.-à-d. this
) à un nouvel objet différent, lorsque vous appelez super
et ce nouvel objet n'a pas la chaîne de prototypes attendue, c'est-à-dire que c'est une instance de Error
pas de CustomError
.
Ce problème peut être résolu de manière élégante en utilisant 'new.target', qui est supporté depuis Typescript 2.2, voir ici : 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; }
}
}
Utilisation de new.target
a l'avantage de ne pas devoir coder en dur le prototype, comme le proposaient certaines autres réponses ici. Cela présente également l'avantage que les classes héritant de CustomError
obtiendra automatiquement la chaîne de prototypes correcte.
Si vous deviez coder en dur le prototype (par ex. Object.setPrototype(this, CustomError.prototype)
), CustomError
lui-même aurait une chaîne de prototypes fonctionnelle, mais toutes les classes héritant de CustomError
seraient rompus, par exemple les instances d'une class VeryCustomError < CustomError
ne serait pas instanceof VeryCustomError
comme prévu, mais seulement instanceof CustomError
.
Voir aussi : https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200