当 Typescript 2.0 生成 JS 时,Bluebird 的过滤捕获被破坏

Bluebird's filtered catch broken when JS is generated by Typescript 2.0

我看到的错误与此相同(来自此处:):

I have a custom error class:

class NetworkError extends Error {
  constructor() {
    super('Network Error');
    this.name = 'NetworkError';
  }
}

And I want to handle it specifically:

import {NetworkError} from '../../common/errors';
someFunc().catch(NetworkError, err => {
  // this is missed
}).catch(err => {
  // this is hit
});

But it's skipping my custom catch and hitting the general catch. If I change it like so, it works:

someFunc().catch({name: 'NetworkError'}, err => {
  // this is hit
}).catch(err => {
  // this is missed
});

Obviously the first way is preferred. What am I missing here?

原因是最新升级到 Typescript 2.0。 具体来说:

As part of substituting the value of this with the value returned by a super(...) call, subclassing Error, Array, and others may no longer work as expected. This is due to the fact that constructor functions for Error, Array, and the like use ECMAScript 6's new.target to adjust the prototype chain; however, there is no way to ensure a value for new.target when invoking a constructor in ECMAScript 5. Other downlevel compilers generally have the same limitation by default.

https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work

此变通办法解决了我的问题,但不适用于 IE 10 和之前的版本: 在任何超级调用之后添加以下代码。

if (Object.setPrototypeOf) {
  Object.setPrototypeOf(this, XHRError.prototype);
} else {
  this.__proto__ = XHRError.prototype;
}