【问题标题】:TypeScript type definition for promise.prototype.finallyPromise.prototype.finally 的 TypeScript 类型定义
【发布时间】:2016-06-22 22:33:28
【问题描述】:

我在想要转换为 TypeScript 的 Node 应用程序中使用了这个名为 promise.prototype.finally 的最终兼容 ES6 Promise 的实现,但是我可以在 DefinitelyTyped 上找到这个包没有可用的类型。在这些情况下,我已经为我需要的功能子集编写了我自己的即兴类型定义,但在这种情况下,它是一个修改 Promise 对象原型的库,我还没有遇到任何传统的方式来表示这个在打字稿中。有什么想法吗?

可能相关:

【问题讨论】:

    标签: typescript es6-promise definitelytyped


    【解决方案1】:

    虽然 Slava 的回答是正确的,但它只处理 finally 块的类型。要真正将 shim 合并到您的代码中,以便您可以编写 p.finally(() => { ... }),您需要调用 shim。

    很遗憾,typings on DefinitelyTyped 目前不支持shim 功能,所以until this is supported,我建议您自己添加类型。

    罢工>

    declare interface Promise<T> {
      finally<U>(onFinally?: () => U | Promise<U>): Promise<U>;
    }
    
    declare module 'promise.prototype.finally' {
      export function shim(): void;
    }
    

    这些类型现在可用。安装

    npm install --save-dev @types/promise.prototype.finally
    

    在您的 TypeScript 代码中,在应用程序引导期间,您可以调用

    import { shim } from 'promise.prototype.finally';
    shim();
    

    这会将finally 块添加到Promise 原型,允许您根据需要使用finally

    【讨论】:

    • 嗯,我无法在 Visual Studio Code 1.20 中使用它 - 它会构建,但是在运行代码时我会收到“找不到模块 'promise.prototype.finally'”错误, altought 模块在 node_modules@types 中可用。想知道这是否值得调查,因为 github.com/Microsoft/TypeScript/issues/20411 添加了对“finally”的原生支持,finally。
    • 只是使用yarn add @types/promise.prototype.finally --dev 为我做到了
    【解决方案2】:

    对于任何想知道如何在没有任何垫片的情况下本机工作的人:从 TS 2.7 开始,这是可能的。

    请注意,TS 2.7 尚未完全兼容(2018 年 2 月 26 日)ES2018。虽然还有一些事情missingPromise.finally made it into the 2.7 release。 tsconfig-schema 也应该已经接受 ES2018 作为目标,但 TS 2.7 不知道 ES2018。现在要使用新功能,例如 Promise.finally,它已经在 2.7 中,您必须在 tsconfig.json 中使用 "target": "ESNEXT"

    然后你就可以写出这样的代码了:

    myAsyncFunction().then
    (
      (var) => console.log("executing then. " + var)
    )
    .catch
    (
      (var) => console.log("executing catch. " + var)
    )
    .finally
    (
      () => console.log("executing finally.")
    )
    

    注意finally will not take any arguments 的性质。

    重要提示:虽然 TS 会正确转换并理解您在做什么,但您仍然需要检查您的 JS-Engine 是否支持 Promise.finally。在我的情况下,我使用的是 NodeJs 8.x,当然生成的 JS 是不可执行的,因为 Promise.Finally 在最新的 NodeJs 10.x nightly builds 中从 开始支持 Node 10.x (稳定),see this link

    【讨论】:

      【解决方案3】:

      您可以编写自己的 d.ts 文件并在 tsconfig.json 文件中引用它。 如果你这样做,你可以为像你自己一样的其他人贡献绝对类型的 git

      更新:

      如果我正确理解您的意思,您可以在自己的 d.ts 文件中扩展现有的 Promise 类。将该方法设为可选,这样它就不会告诉您实际的Promise 类没有正确实现接口。 您需要将其扩展为接口。

      您的 d.ts 文件应如下所示

      declare module 'es6-promise/dist/es6-promise' {
          export interface Promise <R> {
            finally?<U>(onFinally?: () => U | Promise<U>): Promise<U>;
          }
      }
      

      它应该可以正常工作...

      我为您创建了一个项目作为示例: promise-extension-typescript-example

      我向DefinitelyTyped git 存储库创建了一个拉取请求,希望它会被接受,您可以从那里下载它...

      【讨论】:

      • 我很清楚这些要点。我上面描述的情况是特定于该包的,它正在修改现有对象/类,而不是定义新类型或类型集。
      • 我不确定Thenable,但我正在使用 ES6 polyfill es6-promise 中定义的承诺,但 promise.prototype.finally 应该支持任何 ES5 兼容的 Promise 实现。我正在使用的类型是 Promise。在上面的实现中用 Promise 替换 Thenable 对我不起作用,因为 tsc 在 Promise polyfill import { Promise } from 'es6-promise'; 的导入站点上给了我一个错误。
      • 如果您查看 d.ts 文件 es6-promise,您将看到 Promise 实现了 Thenable。在我给你的代码中,我使用新方法扩展了该接口
      • 从我所见,如上所述,通过编写具有相同名称的新接口来扩展接口似乎与 TypeScript 编译器不兼容。
      • 你可以在这里看到它的工作文件:Typescript Playground
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 2019-04-01
      • 2017-08-23
      • 2020-11-11
      • 2016-12-02
      • 2017-11-24
      • 2017-07-13
      相关资源
      最近更新 更多