为自定义打字稿错误实例实施 instanceof 检查?
Posted
技术标签:
【中文标题】为自定义打字稿错误实例实施 instanceof 检查?【英文标题】:Implementing instanceof checks for custom typescript Error instances? 【发布时间】:2019-07-30 15:14:52 【问题描述】:Typescript 有这个instanceof checks on custom errors 问题,但不清楚我们需要做什么才能让instanceof
正常工作。例如对于这个异常,我们如何让instanceof
工作:
/**
* @param message The error message
* @param value The value that violates the constraint
* @param field The name of the field
* @param type The expected type for the field
* @param constraint The name of the constraint violated
* @param code The application or module code for the error
*/
export class IsError extends Error
constructor(
public message:string,
public value: any,
public field?:string,
public type?: string,
public constraint?: string,
public code?:string)
super(message);
this.name = 'IsError';
Object.setPrototypeOf(this, IsError.prototype);
This link says we can manually adjust the prototype,这是我正在做的,但是这个测试没有通过:
it("should be an instance of IsError", () =>
let error = new IsError("This is an IsError", 'value');
expect(error instanceof IsError)).toBeTruthy();
);
更正
我在测试...IsError))
中有一个额外的括号,我误认为测试没有通过。我更新了测试,现在它可以工作了。所以这个问题中的例子IsError
实现是正确的。
IIUC 这个实现在 ES5 中不起作用,但是包含 CoreJS 的 AFAIK 客户端可以。
【问题讨论】:
不扩展 Error 类而只依赖Object.setPrototypeOf
行会发生什么?
试过了 - 检查测试仍然没有通过......
我创建了一个对我有用的基本示例 (here)。我使用 Typescript 3.0.1。
Duh ... 感谢您指出这一点 - 我在开玩笑的测试中多了一个括号,看起来好像测试没有通过。现在一切都好。例子更简单。请把它作为答案发布,我会检查它。
【参考方案1】:
阅读https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
现在,@Mathyn 和 @TmTron 的完整实现答案:
/**
* Base Error.
*/
class BaseError extends Error
constructor(message?: string)
const trueProto = new.target.prototype;
super(message);
Object.setPrototypeOf(this, trueProto);
class Err1 extends BaseError
const e1 = new Err1();
console.log(e1 instanceof Err1); // true
console.log(e1 instanceof Error); // true
class Err2 extends Err1
const e2 = new Err2();
console.log(e2 instanceof Err1); // true
console.log(e2 instanceof Err2); // true
console.log(e2 instanceof Error); // true
class NoBaseErr extends Error
const x = new NoBaseErr();
console.log(x instanceof Error); // true
console.log(x instanceof NoBaseErr); // false !!!
包
import BaseError from 'ts-base-error';
见:https://www.npmjs.com/package/ts-base-error
【讨论】:
【参考方案2】:AFAIK,Object.setPrototypeOf()
需要 es6 - ref
TypeScript#13965 中的这段代码对我有用(在 es5 中)
export class MyError extends Error
__proto__: Error;
constructor(message?: string)
const trueProto = new.target.prototype;
super(message);
// Alternatively use Object.setPrototypeOf if you have an ES6 environment.
this.__proto__ = trueProto;
【讨论】:
【参考方案3】:您的代码中出现的问题(正如您正确指出的那样)是您的断言中多了一个括号。
为了完整起见,一个有效且最小的示例如下所示:
class CustomError extends Error
constructor()
super();
Object.setPrototypeOf(this, CustomError.prototype);
let error = new CustomError();
console.log(error instanceof CustomError); // Will log 'true'
【讨论】:
如果你尝试扩展CustomError
,你需要对constructor()
做同样的事情。
在这种情况下,constructor()
没有扩展基本实现,例如:尝试做new CustomError('Test').message
...以上是关于为自定义打字稿错误实例实施 instanceof 检查?的主要内容,如果未能解决你的问题,请参考以下文章