Definitelytyped: bluebird 3.0 定义不能分配给 ES6 Promises

创建于 2016-09-05  ·  48评论  ·  资料来源: DefinitelyTyped/DefinitelyTyped

bluebird 3.0 定义不能分配给标准的 es6 Promise 定义:

Types of property 'then' are incompatible.
Type 'Bluebird<any>' is not assignable to type 'Promise<any>'.

/cc @lhecker

最有用的评论

@silentorb我通过使用@types/bluebird-global类型定义,然后通过将以下内容添加到我的代码顶部来覆盖全局承诺定义(如果您的目标是 ES2015 平台,您将拥有)执行入口点:

import * as Promise from 'bluebird';
global.Promise = require('bluebird');

以上适用于节点环境(我使用的是 6.10.x)。 如果你使用webpack,那么你可能需要使用类似 _expose-loader_ 的东西。

所有48条评论

@Strate你能发布 tsc 的剩余输出吗? 请尝试打开您本地的bluebird.d.ts并从#10831 中添加这一行。 这能解决你的问题吗?

整个错误:

error TS2322: Type '(entity: BaseEntity) => Bluebird<{ contentType: "ActivityDesktopWidget" | "AddressType" | "Approv...' is not assignable to type 'UpdateEntityFunction<BaseEntity>'.
  Type 'Bluebird<{ contentType: "ActivityDesktopWidget" | "AddressType" | "Approval" | "BaseIntegrationEn...' is not assignable to type 'Promise<BaseEntity>'.
    Types of property 'then' are incompatible.
      Type '{ <U>(onFulfill: (value: { contentType: "ActivityDesktopWidget" | "AddressType" | "Approval" | "B...' is not assignable to type '{ <TResult1, TResult2>(onfulfilled: (value: BaseEntity) => TResult1 | PromiseLike<TResult1>, onre...'.
        Type 'Bluebird<any>' is not assignable to type 'Promise<any>'.

我将[email protected]lib.es2016.d.ts文件一起使用。 添加该行无济于事。

啊,我明白了......我相信这是由于这里缺少这一行。 这意味着对于当前的类型,您必须从onFulfillonReject返回相同类型的U onReject 。 如果有人可以在 npm 和这个 dt 存储库中解决这个问题,那就太酷了。

与此同时,您可能应该将您的.then(success, failure)拆分为.then(success).catch(failure)因为这可能是您做的对吗? 虽然它是官方语法的一部分,但无论如何它确实不是 bluebird 的“首选”语法。

另一种方法是您可以像这样手动指定泛型参数U

.then<SomeType>(() => new SomeType(), (err) => 123); // This is an explicit error because SomeType != number

以确保您从两个回调中返回相同的类型。

@lhecker但我什至不使用thencatch 。 我有这样的事情:

// module 1. Note that bluebird is not imported
export default function<T>(promise: Promise<T>) {} // es6 promise used here

// module 2.
import Promise from "bluebird"
import handler from "./module1"
const promise: Promise<any>
handler(promise) // <-- error is here

似乎可以通过添加另一个then声明来修复它,与 es6 的声明兼容bluebird.d.ts

啊该死的……对不起。 我想我终于应该休息一下了。 😅

因此,请忽略我关于在此期间该做什么的评论:因为无论如何它们都不见了,而且由于我真的没有或至少“不应该”有时间做这样的基本支持之外的任何事情,如果您可以发送 PR 将这些类型添加到两个项目中。 😊

@lhecker完成 :)

只是一个旁注,但我总是建议您在接受承诺时使用PromiseLike 。 它将保证实现最少的承诺接口,因此您可以接受大多数承诺。 然后你可以返回你选择的承诺类型,使它更严格,比如Bluebird<T> ,它有很多额外的方法。 很长一段时间以来,由于 ES6 符号被添加到 ES6 承诺类型中,我的承诺都不可分配。

@blakeembrey在这种情况下使用PromiseLike不是答案,因为 PromiseLike 也有不兼容的 then 版本

不幸的是,TS 版本 2 中的 Promise 类型已更改,因此这些类型不再对应: https :

我们可以重新打开这个问题吗?

有任何更新吗?

@OliverJAsh @arg20你们能提供可自我重现的问题的测试用例吗?

@Strate在这里你有我的错误。 使用 typescript 2.0.3 (lib.es6.d.ts) 和 @types/bluebird v3.0.33

error TS2345: Argument of type 'Bluebird<Db>' is not assignable to parameter of type 'Promise
<Db>'.                                                                                                            
  Types of property 'then' are incompatible.                                                                      
    Type '{ <U1, U2>(onFulfill: (value: Db) => U1 | Thenable<U1>, onReject: (error: any) => U2 | Thenable<U...' is
 not assignable to type '{ <TResult1, TResult2>(onfulfilled: (value: Db) => TResult1 | PromiseLike<TResult1>, onre
jected: ...'.                                                                                                     
      Type 'Bluebird<any>' is not assignable to type 'Promise<any>'.                                              
        Types of property 'then' are incompatible.                                                                
          Type '{ <U1, U2>(onFulfill: (value: any) => U1 | Thenable<U1>, onReject: (error: any) => U2 | Thenable<.
..' is not assignable to type '{ <TResult1, TResult2>(onfulfilled: (value: any) => TResult1 | PromiseLike<TResult1
>, onrejected:...'.                                                                                               
            Type 'Bluebird<any>' is not assignable to type 'Promise<any>'.              

尝试将 Bluebird Promise 转换为 ES6 Promise 会抛出以下内容( bluebirdPromise as Promise<Db>

 error TS2352: Type 'Bluebird<Db>' cannot be converted to type 'Promise<Db>'.                 
  Types of property 'then' are incompatible.                                                                      
    Type '{ <U1, U2>(onFulfill: (value: Db) => U1 | Thenable<U1>, onReject: (error: any) => U2 | Thenable<U...' is  not comparable to type '{ <TResult1, TResult2>(onfulfilled: (value: Db) => TResult1 | PromiseLike<TResult1>, onrejected: ...'.                                                                                                     
      Type 'Bluebird<any>' is not comparable to type 'Promise<any>'.                                              
        Property '[Symbol.toStringTag]' is missing in type 'Bluebird<any>'.         

按照#10831 中的建议添加此内容对我有用

readonly [Symbol.toStringTag]: 'Promise';

此外,转换为 ES6 Promise 也成功了

return new Promise.resolve(bluebirdPromise)

@jmendiara如#10831 中所述,实际上在 bluebird 中没有readonly [Symbol.toStringTag] ,因此,将其添加到 bluebird.d.ts 绝对是错误的:类型应该代表真实世界。
如果 Promise 标准需要readonly [Symbol.toStringTag] ,它也应该添加到 bluebird 本身和 bluebird.d.ts 中。 似乎您应该明确使用 bluebird 和本机承诺之间的转换(这真的很烦人)。
仅供参考:您可以Promise.resolve没有new关键字的情况下使用Promise.resolve

当 bluebird 的承诺无法分配给标准承诺时,就遇到了问题。 在我的情况下,不可能使用Promise.resolve将 bluebird 转换为标准,因为它位于第 3 方对象的深处。 因此,有时让 bluebird 承诺无需转换即可分配给标准版本是合理的。
刚刚在 bluebird 的存储库中创建了功能请求,将Symbol.toStringTag到 bluebird 的实例。

https://github.com/petkaantonov/bluebird/issues/1277

有任何更新吗?

很高兴我找到了这个线程。 以为我要疯了。 真的很想看到解决这个问题。 我在SO上描述了我的问题细节

我在使用 @types/bluebird 3.5.3 和 TypeScript 2.2.2 时遇到了这个问题。

@silentorb我通过使用@types/bluebird-global类型定义,然后通过将以下内容添加到我的代码顶部来覆盖全局承诺定义(如果您的目标是 ES2015 平台,您将拥有)执行入口点:

import * as Promise from 'bluebird';
global.Promise = require('bluebird');

以上适用于节点环境(我使用的是 6.10.x)。 如果你使用webpack,那么你可能需要使用类似 _expose-loader_ 的东西。

@ksnyde :我之前尝试过@types/bluebird-global并且遇到了多个丢失的 Promise 细节。 我考虑修补@types/bluebird-global但最好让@types/bluebird工作。

@silentorb关键是覆盖全局 Promise 引用; 对我来说没有问题。 也就是说,如果它开箱即用当然会很好,但无需等待此解决方案。

这方面有什么进展吗?

我也遇到这个问题。 它归结为如下错误:

type Promise<any> is not assignable to Bluebird<any>

非常令人沮丧。 这也打破了其他类型包的用法,例如sequelize

export interface MissionModel extends Sequelize.Model<MissionInstance, MissionAttributes. {
    create(missionAttributes: MissionAttributes, opsions?: Sequelize.CreateOptions): Promise<MissionInstance>;
}

除非将Promise作为* from "bluebird"导入,否则MissionModel将出现以下错误:

src\server\models\mission.ts(3,18): error TS2430: Interface 'MissionModel' incorrectly extends interface 'Model<MissionInstance, MissionAttributes>'.
  Types of property 'create' are incompatible.
    Type '(MissionAttributes: MissionAttributes, option?: CreateOptions | undefined) => Promise<MissionInst...' is not assignable to type '(values?: MissionAttributes | undefined, options?: CreateOptions | undefined) => Bluebird<Mission...'.
      Type 'Promise<MissionInstance>' is not assignable to type 'Bluebird<MissionInstance>'.
        Types of property 'then' are incompatible.
          Type '<TResult1 = MissionInstance, TResult2 = never>(onfulfilled?: ((value: MissionInstance) => TResult...' is not assignable to type '{ <U>(onFulfill?: ((value: MissionInstance) => U | PromiseLike<U>) | undefined, onReject?: ((erro...'.
            Type 'Promise<any>' is not assignable to type 'Bluebird<any>'.

@Strate你能重新打开这个问题吗?
再想一想,我将提交一个新的、更有针对性的文件。

我真的很讨厌浪费时间来解决这种打字稿问题。 因为代码很清楚,但是要通过 tsc 还得做更多的额外工作。 我修复它的简单方法是创建一个类型为 any 的临时变量。 然后将其转换为您的目标 Promise。 如:

'''
const p: any = getPromise();
返回> p;
'''

@flyingsky (等人)首先,我想再次提醒大家,永远不可能

另一方面,将 Bluebird 承诺分配给本地承诺应该是可能且正确的。 但是这里的许多人都认为这应该立即起作用,但事实并非如此。

这样做的原因是,虽然 Bluebird 以本机兼容的方式公开所有常见的函数,但它_不_公开一个特定字段: [Symbol.toStringTag]字段必须是"promise" 。 请参见此处: https :

const p: any = getPromise();
return <Promise>p;

这在技术上是不安全和不正确的类型。

我考虑修补@types/bluebird-global ,但最好让@types/bluebird工作。

bluebird-global提供了一个与bluebird完全不同的用例:它存在的情况是,如果您使用Bluebird覆盖全局Promise变量的类型非常不安全的路径。 Bluebird 。 (这是不安全的,因为简单地覆盖它并不意味着您依赖的每个包都不会继续使用本机承诺。)

如果此问题中的任何人想看到进展,我建议为已经提到的 Bluebird 问题打开 PR: https :

如果此问题中的任何人想看到进展,我建议为已经提到的 Bluebird 问题打开 PR:petkaantonov/bluebird#1277

看起来这个 PR 已经创建: https :

@ksnyde - 你的@types/bluebird-global建议对我有用,略有修改:

import * as Promise from 'bluebird'
global.Promise = Promise

否则我会得到error TS6133: 'Promise' is declared but its value is never read.预期tsconfig.json"noUnusedLocals": true

谢谢你。

我正在使用bluebird-global但仍然出现此错误:

“Bluebird”类型中缺少属性“[Symbol.toStringTag]”'

添加这一行解决了这个问题https://github.com/DefinitelyTyped/DefinitelyTyped/pull/10831/files

有没有办法在不修改 bluebird 的类型的情况下在本地修复它?

+1

@gdpaulmil感谢您的建设性评论!

它促使我查看 Bluebird 的情况。
原来https://github.com/petkaantonov/bluebird/pull/1421是在 11 天前合并的,这意味着他们终于增加了对Symbol.toStringTag ! 🎉

这反过来意味着可以通过重新提交 #10831 立即解决此问题。 只需将"Promise"换成"Object" 。 老实说,我会立即审查它。 🙂

@lhecker ,创建了 #35353 来解决这一切!

嘿,我只是想让大家知道这个问题已经在@types/bluebird v3.5.27 中修复
您现在可以享受将所有这些 Bluebird 分配给所有这些 Promise 的乐趣。 🎉
不过,您必须为此使用 TypeScript 3.2 或更高版本。 (见#34805)

PS:再次感谢@JoshuaKGoldberg处理 Bluebird PR。 🙂👍

是:

import * as Promise from 'bluebird';
global.Promise = require('bluebird');

仍然适用于 es2017?

除了具有先前版本作为依赖项并且没有得到备忘录的所有其他软件包...... request-promise,knex,......您在此更新中破坏了很多代码。 Typescript 编译器到处抛出无意义的错误,Typescript 3.3、3.4、3.5 ......似乎无关紧要。

如果它对任何人有帮助,正如上面提到的,我有最简单的时间只是不将我的全局 Promise 对象换成 BB。 我没有遇到过一件事与另一件事兼容的任何问题。

@jacklinton我相信你已经知道单元测试已经到位,以验证所有受影响的包仍然使用给定的 TypeScript 版本构建,而不会“抛出无意义的错误”。
例如,这里有一个项目,显示使用最新的 Bluebird 类型的请求承诺: https :
由于我无法重现您的问题,如果您能提供一个显示您所看到的问题的最小示例,那就太好了。

很难知道从哪里开始,但所有其他软件包都是最新的
Error:(19, 3) TS2741: Property '[Symbol.toStringTag]' is missing in type 'Bluebird<string[]>' but required in type 'Bluebird<string[]>'.
如果我删除@types/bluebird,这些错误就会消失。 我可以用我的时间做出的唯一猜测是,并非所有其他需要这些类型的包都已经赶上了。 我怀疑 Knex 可能是罪魁祸首,但我不知道。 它获取自己对该包的先前版本的依赖。

此错误听起来好像您安装了@types/bluebird两个版本。 您应该尝试查看是否可以将那棵树展平,以便您只有其中一个。

knex 0.17.3 依赖于@types/bluebird的最新 3.5.27 版本顺便说一句。 如果您有最新版本的 knex,我想它实际上应该可以工作。
你的第二个@types/bluebird副本也是如此:它也应该是 3.5.27。

感谢您的响应@lhecker 。 我不是故意批评的,我道歉。 您显然一直在为此努力,这是我们期待已久的事情。 感谢您在 Bluebird 做出更改后如此迅速地发布此更新的辛勤工作。 我会让这个臃肿的单体以一种或另一种方式工作。

@lhecker能否请您重新发布您的request-promise-sample,因为它似乎已经消失了。 😢

@VictorioBerra技巧

import * as Promise from 'bluebird';
global.Promise = require('bluebird');

让我在 Node.js 12 上出现以下错误:

global.Promise = 承诺;
“typeof Bluebird”类型缺少“Function”类型中的以下属性:apply、call、bind、length 等 4 个。

我正在使用 TypeScript v3.7.4、bluebird v3.7.2 和 @types/bluebird-global v3.5.12。

@bennn我没有代码了。 我非常抱歉。 我在修复请求承诺问题后删除了它。
确保您使用 3.5.29 的最新版本的@types/bluebird

我遇到了与@benynn相同的错误,使用所有 bluebird、@types/bluebird-global 和 TypeScript 的最新版本

当前版本的 Bluebird 3.7.2 和 TypeScript 3.6 似乎唯一可行的选择是根本不使用 Bluebird 类型。

在应用程序入口点,我用 Bluebird 替换了原生 Promise 构造函数,然后使用原生 Promise API 使用 Bluebird:

import * as Bluebird from "bluebird";
global.Promise = Bluebird;

new Promise((resolve, reject) => {
  // this is actually a Bluebird object
});

坦率地说,我个人认为你们做错了什么。 😖
我已经重建了我的最小request-promise-sample项目,它显示了您绝对 100% 绝对可以......

  • Bluebird构造函数分配给global.Promise
  • 使用 request-promise 没有编译错误
  • Bluebird类实例分配给Promise接口(这就是这个问题的所在)

_也就是说,此问题已关闭,不应用于继续偏离主题的讨论。_
上面的讨论是题外话,因为这张票是关于 Bluebird promises 不能分配给 ES6/native Promises。 但如上所示,这个问题早已得到修复。
如果您在 Bluebird 中使用@types/[email protected]时遇到问题,请参阅https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42084

@lhecker
感谢您的答复。 我试过你的项目,它也不起作用:
Annotation 2020-03-21 084422

安装@types/[email protected]也无济于事:
Annotation 2020-03-21 084750

修改后的项目可以在这里找到:
https://github.com/chebum/request-promise-sample

@chebum您上面的评论并没有明确表示您正在尝试将异步函数键入为返回Bluebird<T>函数。 在那种情况下,我本可以告诉你不幸的是这是不可能的。 正如您在编译器的输出中看到的,您_必须_从异步函数返回一个Promise<T>类型。

如果您想放弃一点类型安全,您可以执行以下操作:

  1. 添加@types/bluebird-global作为依赖
  2. 覆盖全局 Promise 构造函数: window.Promise = Bluebird as any;
  3. 写: async function testFn(): Promise<void>
  4. 全局Promise<T>类型现在几乎与Bluebird<T> ,您应该能够使用所有重要的 Bluebird 功能。

如果您遇到任何Symbol.species错误等,请_不要_使用此票,而是使用 #42084。

此页面是否有帮助?
0 / 5 - 0 等级