Definitelytyped: La définition de bluebird 3.0 n'est pas attribuable aux promesses ES6

Créé le 5 sept. 2016  ·  48Commentaires  ·  Source: DefinitelyTyped/DefinitelyTyped

La définition bluebird 3.0 n'est pas attribuable à la définition standard es6 Promise :

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

/cc @lhecker

Commentaire le plus utile

@silentorb J'ai fait fonctionner cela en utilisant la définition de type @types/bluebird-global , puis en remplaçant la définition de promesse globale (que vous aurez si vous ciblez une plate-forme ES2015) en ajoutant ce qui suit en haut de mon code point d'entrée d'exécution :

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

Ce qui précède fonctionne pour l'environnement de nœud (j'utilise 6.10.x). Si vous utilisez webpack, vous devrez peut-être utiliser quelque chose comme _expose-loader_.

Tous les 48 commentaires

@Strate Pouvez-vous publier la sortie restante de tsc? Et s'il vous plaît essayez d'ouvrir votre bluebird.d.ts local et ajoutez cette seule ligne de #10831 . Cela résout-il votre problème ?

Erreur totale :

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>'.

J'utilise [email protected] avec lib.es2016.d.ts fichier

Ah je vois... Je crois que c'est à cause de cette ligne manquante ici . Cela signifie qu'avec les saisies actuelles, vous devez renvoyer le même type U à la fois à partir de onFulfill ainsi que de onReject . Ce serait super cool si quelqu'un pouvait résoudre ce problème dans le npm et ce référentiel dt d'ailleurs.

En attendant, vous devriez probablement diviser vos .then(success, failure) en .then(success).catch(failure) puisque c'est probablement ce que vous avez bien fait ? Bien que cela fasse partie de la syntaxe officielle, ce n'est de toute façon pas la "préférée" avec bluebird.

L'alternative est que vous pouvez spécifier manuellement le paramètre générique U comme ceci

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

pour vous assurer que vous retournez le même type à partir des deux rappels.

@lhecker mais je n'utilise même pas then ou catch . J'ai quelque chose comme ça :

// 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

Il semble que cela pourrait être corrigé en ajoutant une autre déclaration then , compatible avec celle d'es6 à bluebird.d.ts

Ah putain... désolé. Je suppose que je devrais enfin faire une pause. ??

Ignorez donc mes commentaires sur ce qu'il faut faire en attendant : puisqu'ils manquent de toute façon et puisque je n'ai vraiment pas ou du moins "ne devrais pas" avoir le temps de faire autre chose que l'assistance de base comme celle-ci, ce serait grandement apprécié si vous pouvez envoyer des PR pour ajouter ces saisies aux deux projets. ??

@lhecker terminé :)

Juste une remarque, mais je recommande toujours d'utiliser PromiseLike lorsque vous acceptez des promesses. Il garantira l'interface de promesse minimale implémentée afin que vous puissiez accepter la plupart des promesses. Ensuite, vous pouvez retourner le type de promesse de votre choix, le rendant plus strict comme Bluebird<T> qui a de nombreuses méthodes supplémentaires. Pendant longtemps, aucune de mes promesses n'était assignable à cause des symboles ES6 ajoutés aux types de promesses ES6.

@blakeembrey utilisant PromiseLike dans ce cas n'est pas la réponse, car PromiseLike a également une version incompatible de then

Malheureusement, les typages Promise ont changé dans TS version 2 et ces typages ne correspondent donc plus : https://github.com/Microsoft/TypeScript/blob/070aa83cc06b2974639bbefcde98e6e2fb5fe693/src/lib/es2015.promise.d.ts

Pouvons-nous rouvrir ce problème?

Des mises à jour à ce sujet ?

@ OliverJAsh @ arg20 pourriez-vous fournir un cas de test auto-reproductible de votre problème ?

@Strate ici, vous avez mon erreur. Utilisation de typescript 2.0.3 (lib.es6.d.ts) et @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>'.              

Essayer de convertir la promesse Bluebird en une promesse ES6 renvoie ce qui suit ( 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>'.         

l'ajout de ceci comme proposé dans #10831 a fonctionné pour moi

readonly [Symbol.toStringTag]: 'Promise';

aussi, la conversion en une promesse ES6 a fait l'affaire

return new Promise.resolve(bluebirdPromise)

@jmendiara comme indiqué dans #10831, il n'y a pas de readonly [Symbol.toStringTag] dans bluebird en fait, donc, ajouter ceci à bluebird.d.ts est définitivement faux : les frappes doivent représenter le monde réel.
Si le standard Promise nécessite readonly [Symbol.toStringTag] , il doit être ajouté à bluebird lui-même et à bluebird.d.ts également. Il semble que vous devriez définitivement utiliser la conversion entre les promesses bluebird et natives (ce qui est vraiment ennuyeux).
Pour info : vous pouvez utiliser Promise.resolve sans mot-clé new .

Je viens de rencontrer un problème lorsque la promesse de bluebird n'est pas attribuable à une promesse standard. Et dans mon cas, il est impossible de convertir bluebird en standard avec Promise.resolve , car il est profondément enfoui dans un objet tiers. Ainsi, il est parfois raisonnable d'avoir la promesse de bluebird d'être assignable à un standard sans conversion.
Je viens de créer une demande de fonctionnalité dans le référentiel de bluebird, pour ajouter Symbol.toStringTag aux instances de bluebird.

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

Des mises à jour à ce sujet ?

Content d'avoir trouvé ce fil. Je pensais devenir fou. J'aimerais vraiment voir un correctif pour cela. J'ai décrit les détails de mon problème sur SO

Je rencontre ce problème avec @types/bluebird 3.5.3 et TypeScript 2.2.2.

@silentorb J'ai fait fonctionner cela en utilisant la définition de type @types/bluebird-global , puis en remplaçant la définition de promesse globale (que vous aurez si vous ciblez une plate-forme ES2015) en ajoutant ce qui suit en haut de mon code point d'entrée d'exécution :

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

Ce qui précède fonctionne pour l'environnement de nœud (j'utilise 6.10.x). Si vous utilisez webpack, vous devrez peut-être utiliser quelque chose comme _expose-loader_.

@ksnyde : J'ai déjà essayé @types/bluebird-global et j'ai rencontré plusieurs détails de promesse manquants. J'ai envisagé de patcher @types/bluebird-global mais il serait préférable que @types/bluebird fonctionne.

@silentorb, la clé consiste à remplacer la référence globale Promise ; fonctionne sans problème pour moi. Cela dit, ce serait certainement bien si cela fonctionnait immédiatement, mais il n'est pas nécessaire d'attendre avec cette solution.

Des progrès à ce sujet ?

Je reçois également ce problème. Cela se résume à des erreurs comme les suivantes :

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

Très frustrant. Cela brise également les utilisations d'autres packages de saisie, tels que sequelize .

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

MissionModel aura l'erreur suivante sauf si Promise est importé en tant que * from "bluebird" :

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 pourriez-vous s'il vous plaît rouvrir le problème?
À la réflexion, je vais juste en déposer un nouveau, plus ciblé.

Je déteste vraiment perdre du temps à résoudre ce genre de problème dactylographié. Parce que le code est très clair, mais pour passer tsc, vous devez faire plus de travail supplémentaire. La façon la plus simple de résoudre ce problème est de créer une variable temporaire avec le type any. Ensuite, convertissez-le en votre promesse cible. Tel que:

'''
const p: any = getPromise();
revenir>p;
'''

@flyingsky (et. al.) Tout d'abord, je voudrais rappeler à tout le monde qu'il ne sera jamais possible d'attribuer directement des promesses natives à celles de Bluebird, car les promesses Bluebird fournissent des extensions qui n'existent pas dans l'implémentation native.

Attribuer des promesses Bluebird à des natifs devrait en revanche être possible et à juste titre. Mais beaucoup ici ont l'impression que cela devrait fonctionner pour le moment, ce qui n'est certainement pas le cas.

La raison en est que bien que Bluebird expose toutes les fonctions communément connues d'une manière compatible native, il _n'expose pas_ un champ particulier : le champ [Symbol.toStringTag] doit être "promise" . Voir ici : https://github.com/petkaantonov/bluebird/issues/1277. Cela rend Bluebird strictement incompatible avec les promesses natives. Alors...

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

Ceci est techniquement de type dangereux et incorrect.

J'ai envisagé de patcher @types/bluebird-global , mais il serait préférable que @types/bluebird fonctionne.

bluebird-global sert un cas d'utilisation totalement différent de celui de bluebird : il existe au cas où vous emprunteriez la voie très dangereuse consistant à écraser la variable globale Promise avec Bluebird . (C'est dangereux car le simple écrasement ne signifie pas que chaque paquet dont vous dépendez ne continuera pas à utiliser les promesses natives.)

Si quelqu'un dans ce numéro veut voir des progrès, je suggère d'ouvrir un PR pour le problème Bluebird déjà mentionné : https://github.com/petkaantonov/bluebird/issues/1277

Si quelqu'un dans ce numéro veut voir des progrès, je suggère d'ouvrir un PR pour le problème Bluebird déjà mentionné : petkaantonov/bluebird#1277

On dirait que ce PR a été créé : https://github.com/petkaantonov/bluebird/pull/1421

@ksnyde – Votre @types/bluebird-global fonctionne pour moi, légèrement modifiée :

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

Sinon j'obtiens error TS6133: 'Promise' is declared but its value is never read. Ce qui est attendu pour tsconfig.json avec "noUnusedLocals": true .

Merci.

J'utilise bluebird-global mais j'obtiens toujours cette erreur :

La propriété '[Symbol.toStringTag]' est manquante dans le type 'Bluebird'

L'ajout de cette ligne résout le problème https://github.com/DefinitelyTyped/DefinitelyTyped/pull/10831/files

Existe-t-il un moyen de le réparer localement sans modifier les frappes de bluebird?

+1

@gdpaulmil Merci pour votre commentaire constructif !

Cela m'a incité à jeter un œil à l'état des choses chez Bluebird.
Il s'avère que https://github.com/petkaantonov/bluebird/pull/1421 a été fusionné il y a 11 jours, ce qui signifie qu'ils ont finalement ajouté le support pour Symbol.toStringTag ! ??

Cela signifie à son tour que ce problème peut être résolu immédiatement en soumettant à nouveau #10831. On n'aura qu'à échanger "Promise" avec "Object" . Je le réviserais honnêtement tout de suite. ??

@lhecker , a créé le #35353 pour tout éclaircir !

Hé, je voudrais juste vous faire savoir que ce problème a été corrigé dans la v3.5.27 de @types/bluebird .
Vous pouvez maintenant profiter de la possibilité d'attribuer tous ces Bluebirds à toutes ces promesses. ??
Vous devrez cependant utiliser TypeScript 3.2 ou une version plus récente pour cela. (Voir #34805)

PS : Merci encore @JoshuaKGoldberg d' avoir traité avec le Bluebird PR. ??

Est:

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

Toujours applicable pour es2017 ?

À l'exception de tous les autres packages qui ont la version précédente en tant que dépendance et n'ont pas reçu le mémo... request-promise, knex,... vous venez de casser beaucoup de code avec cette mise à jour. Le compilateur Typescript jette des erreurs absurdes partout, Typescript 3.3, 3.4, 3.5... ne semble pas avoir d'importance.

Si cela peut aider quelqu'un, comme mentionné plus haut, j'ai eu le plus de facilité à ne PAS échanger mon objet Promise global contre BB. Je n'ai rencontré aucun problème où une chose était compatible avec une autre.

@jacklinton Je suis sûr que vous savez déjà que des tests unitaires sont en place pour vérifier que tous les packages concernés sont toujours construits avec la version TypeScript donnée sans "lancer d'erreurs absurdes".
Par exemple, voici un projet qui montre que request-promise fonctionne avec les derniers typages Bluebird : https://github.com/lhecker/request-promise-sample
Comme je ne peux pas reproduire votre problème, ce serait génial si vous pouviez fournir un exemple minimal qui montre les problèmes que vous rencontrez.

Il est difficile de savoir par où commencer, mais avec tous les autres packages à jour
Error:(19, 3) TS2741: Property '[Symbol.toStringTag]' is missing in type 'Bluebird<string[]>' but required in type 'Bluebird<string[]>'.
Si je supprime @types/bluebird, ces erreurs disparaissent. La seule conjecture que je peux faire avec le temps dont je dispose est que tous les autres packages qui ont besoin de ces types n'ont pas encore rattrapé leur retard. Je suspecte Knex d'être un coupable probable, mais je ne sais pas. Il récupère sa propre dépendance de la version précédente de ce package.

Cette erreur sonne comme si vous aviez deux versions de @types/bluebird installées. Vous devriez essayer de voir si vous pouvez aplatir cet arbre pour n'en avoir qu'un.

knex 0.17.3 dépend de la dernière version 3.5.27 des typages @types/bluebird ailleurs. Si vous avez une version à jour de knex, cela devrait fonctionner, je suppose.
Il en va de même pour votre deuxième copie de @types/bluebird : il devrait également être 3.5.27.

Merci d'être réactif @lhecker . Je ne voulais pas paraître critique, je m'en excuse. Vous avez clairement travaillé dur là-dessus et c'est quelque chose que nous attendons tous depuis longtemps. Merci pour votre travail acharné pour sortir cette mise à jour si rapidement après que Bluebird a fait le changement. Je vais faire fonctionner ce monolithe gonflé comme il est censé le faire d'une manière ou d'une autre.

@lhecker pouvez-vous s'il vous plaît republier votre demande-promesse-échantillon car il semble avoir disparu. ??

@VictorioBerra le truc avec

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

me donne l'erreur suivante sur Node.js 12 :

global.Promise = Promesse;
Il manque les propriétés suivantes du type 'typeof Bluebird' dans le type 'Function' : apply, call, bind, length et 4 autres.

J'utilise TypeScript v3.7.4, bluebird v3.7.2 et @types/bluebird-global v3.5.12.

@bennyn je n'ai plus le code. Je suis vraiment désolé. Je l'ai supprimé une fois le problème de demande-promesse résolu.
Assurez-vous d'utiliser la dernière version de @types/bluebird à 3.5.29.

J'ai la même erreur que @bennyn , avec les dernières versions de tous les bluebird, @types/bluebird-global et TypeScript

Il semble que la seule option viable avec la version actuelle de Bluebird 3.7.2 et TypeScript 3.6 soit de ne pas utiliser du tout les typages Bluebird.

Au point d'entrée de l'application, je remplace le constructeur natif de Promise par Bluebird et j'utilise Bluebird à l'aide de l'API native de promesse après cela :

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

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

Personnellement, franchement, je pense que vous faites quelque chose de mal de votre côté. ??
J'ai reconstruit mon projet minimal request-promise-sample qui montre comment vous pouvez absolument à 100%...

  • affecter le constructeur Bluebird à global.Promise
  • utiliser request-promise sans erreurs de compilation
  • assign Bluebird des

_Cela dit, ce problème a été clos et ne doit pas être utilisé pour des discussions hors sujet continues._
La discussion ci-dessus est hors sujet, car ce ticket concerne les promesses Bluebird ne pouvant pas être attribuées aux promesses ES6/natives. Mais comme indiqué ci-dessus, ce problème est résolu depuis longtemps.
Si vous rencontrez des problèmes pour utiliser @types/[email protected] avec Bluebird, veuillez plutôt consulter https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42084 .

@lhecker
Merci pour la réponse. J'ai essayé ton projet et ça ne marche pas non plus :
Annotation 2020-03-21 084422

L'installation de @types/[email protected] n'aide pas non plus :
Annotation 2020-03-21 084750

Le projet modifié peut être trouvé ici:
https://github.com/chebum/request-promise-sample

@chebum Votre commentaire ci-dessus n'a pas clairement indiqué que vous essayez de taper des fonctions asynchrones comme renvoyant un Bluebird<T> . Dans ce cas, j'aurais déjà pu vous dire que ce n'est malheureusement pas possible. Comme vous pouvez le voir par la sortie de votre compilateur, vous devez retourner un type Promise<T> partir d'une fonction asynchrone.

Si vous souhaitez renoncer à un peu de votre sécurité de type, vous pouvez cependant procéder comme suit :

  1. Ajouter @types/bluebird-global comme dépendance
  2. Remplacez le constructeur Promise global : window.Promise = Bluebird as any;
  3. Écrire : async function testFn(): Promise<void>
  4. Le type global Promise<T> est maintenant presque identique à Bluebird<T> et vous devriez pouvoir utiliser toutes les fonctionnalités importantes de Bluebird.

Si vous rencontrez des erreurs Symbol.species , etc., veuillez _n'utilisez pas_ ce ticket mais plutôt le #42084.

Cette page vous a été utile?
0 / 5 - 0 notes