属性“ allSettled”在类型“ PromiseConstructor”上不存在。ts(2339)

时间:2020-02-18 07:43:35

标签: javascript typescript es6-promise

我正在尝试将Promise.allSettled API与TypeScript结合使用。代码在这里:

server.test.ts

it('should partial success if QPS > 50', async () => {
  const requests: any[] = [];
  for (let i = 0; i < 51; i++) {
    requests.push(rp('http://localhost:3000/place'));
  }
  await Promise.allSettled(requests);
  // ...
});

但是TSC抛出错误:

类型“ PromiseConstructor”上不存在属性“ allSettled”。ts(2339)

我已经将这些值添加到lib中的tsconfig.json选项中:

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "ES2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "lib": [
      "ES2015",
      "ES2016",
      "ES2017",
      "ES2018",
      "ES2019",
      "ES2020",
      "ESNext"
    ] 
   // ...
}

TypeScript版本:"typescript": "^3.7.3"

那么,我该如何解决呢?我知道我可以使用替代模块,但我对本机使用TypeScript感到好奇。

5 个答案:

答案 0 :(得分:21)

The types for Promise.allSettled()仅在一月份进行了合并,显然将在TypeScript 3.8中发布。

作为临时解决方案,您可以自己为该函数声明一个模拟类型:

declare interface PromiseConstructor {
    allSettled(promises: Array<Promise<any>>): Promise<Array<{status: 'fulfilled' | 'rejected', value?: any, reason?: any}>>;
}

答案 1 :(得分:6)

现在是ES2020和第4阶段,因此没有polyfill的情况并非在所有地方都可用。输入并合并到TS中。尝试安装最新的@ types / node软件包,看看是否能将其插入。

更新:当它着陆时,似乎将es2020.promise添加到库中。

更新:npm i typescript@3.8.0-beta呼呼!

答案 2 :(得分:5)

在较旧的 Typescript 版本中使用它的解决方法

await (Promise as any).allSettled(promises);

答案 3 :(得分:3)

要使其在Linux上运行,我需要最新的打字稿版本:

sudo npm install -g typescript@latest

然后在tsconfig中,当前需要ES2020.Promise库。我完整的tsconfig:

{
  "compilerOptions": {
    "sourceMap": true,
    "module": "commonjs",
    "target": "es5",
    "jsx": "react",
    "esModuleInterop": true,
    "allowJs": true,
    "outDir": "./dist",
    "lib": [
      "ES2020.Promise",
    ]
  },
  "include": [
    "./src"
  ],
  "exclude": [
    "./node_modules",
    "./build"
  ],
  "compileOnSave": true,
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    }
  }
}

用法:const results = await Promise.allSettled(BatchOfPromises);

答案 4 :(得分:1)

有一个提供相同功能 (https://www.npmjs.com/package/promise.allsettled) 的 shim 库,但请注意,它需要显式导入 (var allSettled = require('promise.allsettled');)。

如果您使用的是 typescript,则等效的类型包是 https://www.npmjs.com/package/@types/promise.allsettled,但请注意,类型名称与 ES2020 的官方实现不匹配,因此如果您想要精确的直接替换,则需要添加一个新的 TS 文件来为类型设置别名并使其在全局命名空间中可用:

import { PromiseRejection, PromiseResolution, PromiseResult } from 'promise.allsettled';

// https://stackoverflow.com/a/59499895/323177
export {}

// TechDebt: Remove once project is migrated to ES2020
// Global type aliases are required because the promise.allsettled shim doesn't match the types of the actual 
// ES2020 implementation
declare global {
    export type PromiseFulfilledResult<T> = PromiseResolution<T>;
    
    export type PromiseRejectedResult = PromiseRejection<any>;
    
    export type PromiseSettledResult<T> = PromiseResult<T, any>;

    export class PromiseConstructor {
        /**
         * Creates a Promise that is resolved with an array of results when all
         * of the provided Promises resolve or reject.
         * @param values An array of Promises.
         * @returns A new Promise.
         */
         allSettled<T extends readonly unknown[] | readonly [unknown]>(values: T):
             Promise<{ -readonly [P in keyof T]: PromiseSettledResult<T[P] extends PromiseLike<infer U> ? U : T[P]> }>;

        /**
         * Creates a Promise that is resolved with an array of results when all
         * of the provided Promises resolve or reject.
         * @param values An array of Promises.
         * @returns A new Promise.
         */
        allSettled<T>(values: Iterable<T>): Promise<PromiseSettledResult<T extends PromiseLike<infer U> ? U : T>[]>;
    }
}