记一次关于extends的bug
记录一次关于用
typescript封装restfulapi碰到的问题
这是我在 learn_koa 里面遇到的一个问题.
场景复现:
我需要封装Error到一个基类上面,然后后续所有自定义的异常全部继承这个基类,以后处理业务的时候就可以争对性处理。以下是js 的实现。
1 | class BaseError extends Error { |
如上,我用了一个随机数来模拟处理业务出错的情况,在碰到已知的错误时我们可以用已有的逻辑来处理,比如参数校验错误了,直接通知前端错误,请求第三方出错了,就通知系统的维护人员。本质上的核心代码就是这一句:
1 | (new CustomError()) instanceof BaseError; // true |
在这里面的示例是可以返回true的,但是我在迁移到ts的时候。发现:
1 | (new CustomError()) instanceof BaseError; // false |
你没有看错,是false,当然这只在tsconfig 设置 compilerOptions 打包至es5的情况下,es6不存在以上的问题,但是目前大部分项目还是要降级到es5。
那么,这是为什么呢?我们可以通过两个原型链来看看。
1 | console.log((new CustomError()).__proto__) // Error {} |
如此,我们可以清楚的看到我们自定义的对象实例的本质是Error对象,并不是BaseError, 所以我们使用instanceof的时候是false。
那,有什么办法可以改变实例后的原型链么?
其实TS官方已经给出了答案,只需要在构造函数下加入下面一句就可以了
1 | Object.setPrototypeOf(this, new.target.prototype); |
完整实例如下:
1 |
|
我曾经被这个问题困扰了很久,于是把这个记录下来,以方便后续查看。