流:如何扩展本机JS对象(尤其是Promise)?

时间:2018-07-27 05:09:03

标签: flowtype

// @flow
type Deferred = Promise<any> & {
  reject: Function;
  resolve: Function;
};


/** Deferred based on Promise
@return {Promise} */
export default (): Deferred => {
  let res, rej;
  let deferred: Deferred = Object.assign(
    new Promise( ( resolve, reject ) => {
      res = resolve;
      rej = reject;
    }),
    { 'resolve': res, 'reject': rej }
  );

  return deferred;
};

现在此代码给出了这样的错误:

  • 无法将Object.assign(...)分配给deferred,因为:
    • reject [1]中缺少属性Promise,但是对象类型为[2]。
    • resolve [1]中缺少属性Promise,但是对象类型为[2]。
  • reject [1]中缺少属性Promise
  • resolve [1]中缺少属性Promise

问题是:如何正确无误地记录此代码?

1 个答案:

答案 0 :(得分:1)

  1. 使用any不是一个好主意。
  2. 使用Function并不是一个好主意,因为它只是any的别名。
  3. 最好不要使用&:它已损坏。请改用类型传播。
  4. 如果您真的想扩展Promise,只需像这样https://flow.org/try/#0PTAEAEDMBsHsHcBQBjaBDAzh0ARAppHgE5F4AmAPACoB8oeAHgC54B2Z2ACkbALYCWGPNToBvRKFABiUhljQAbngBcoABRUAlKAC8dfIRLkRoAD6gFsfmQDcE6aQBWeZE1VqBDctr24CxUkpaMwsrW3t7ZFhWDCYiAFdXWCI1SFYAfndZeSVM9S1dOk9yABpQJxcmPI9+LzIfItrvQtDrbXFJSSiYplAABx4GAE9dUFEAXztO0Ax4vuI1NWzFPDKK1wax+2mB2GGAOmWlUaO8Ken+waHDvGdXE9vK8+n+SHU07TSlvDkVtceNs9QONNECmAALQT7GQ-HJ4Ua7A6nMGQjDQ9a9HSXPbXDHncYRSSnb6zaBuUBaVQGALGYIdToQqEw35KEnxMmg7blPBMeJEVigRkYfGIewYtQBZKqYr1Kn+IxBMRcoXogFMCUkZKc6akXn8wWokWSRCTUXdWKgMgEUasPDwPyGQJqTmIECgeDJADWGEQVsgNxZeDUAEZNPsIWxFgxVKx4rwAEbETbm+R4fZwADmagYmk5bqiRlc0BGGHBCGwaAFkqIvoIAbhIbDEdYUdUsSI-FYGeT0V+acz2dzdkQjD6yV6frQ7N61IVdiAA扩展
class Deferred<T> extends Promise<T> {
  #resolve: (T) => Deferred<T> | void;
  #reject: (mixed) => Deferred<T> | void;

  constructor(fn?: (resolve?: (T) => mixed, reject?: (mixed) => mixed) => void) {
    const proxy = {};
    super((resolve, reject) => {
      proxy.resolve = resolve;
      proxy.reject = reject;
      if (fn) fn(resolve, reject);
    });
    this.#resolve = proxy.resolve;
    this.#reject = proxy.reject;
  }

  resolve(result: T): Deferred<T> {
    this.#resolve(result);
    return this;
  }

  reject(error: mixed): Deferred<T> {
    this.#reject(error);
    return this;
  }
};