Definitelytyped: A definição do bluebird 3.0 não pode ser atribuída ao ES6 Promises

Criado em 5 set. 2016  ·  48Comentários  ·  Fonte: DefinitelyTyped/DefinitelyTyped

A definição do bluebird 3.0 não pode ser atribuída à definição da promessa es6 padrão:

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

/ cc @lhecker

Comentários muito úteis

@silentorb Eu @types/bluebird-global e, em seguida, substituindo a definição de promessa global (que você terá se estiver visando uma plataforma ES2015), adicionando o seguinte no topo do meu código ponto de entrada de execução:

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

O acima funciona para o ambiente de nó (estou usando 6.10.x). Se você estiver usando o webpack , pode ser necessário usar algo como _expose-loader_.

Todos 48 comentários

@Strate Você pode postar a saída restante do tsc? E, por favor, tente abrir seu bluebird.d.ts e adicionar esta única linha de # 10831 . Isso resolve o seu problema?

Erro total:

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

Estou usando [email protected] com o arquivo lib.es2016.d.ts . Adicionar essa linha não ajuda.

Ah entendo ... acredito que seja devido a essa linha faltando aqui . Isso significa que com as digitações atuais você deve retornar o mesmo tipo U tanto de onFulfill quanto de onReject . Seria muito legal se alguém pudesse corrigir isso no npm e neste repositório dt btw.

Nesse ínterim, você provavelmente deve dividir seus .then(success, failure) em .then(success).catch(failure) já que provavelmente foi isso que você fez certo? Embora seja parte da sintaxe oficial, não é realmente a "preferida" no bluebird.

A alternativa é que você poderia especificar manualmente o parâmetro genérico U assim

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

para garantir que você retorne o mesmo tipo de ambos os retornos de chamada.

@lhecker, mas eu nem mesmo uso then ou catch . Eu tenho algo assim:

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

Parece que poderia ser corrigido adicionando mais uma declaração then , compatível com a declaração de es6 para bluebird.d.ts

Ah, droga ... desculpe. Acho que devo finalmente fazer uma pausa. 😅

Portanto, ignore meus comentários sobre o que fazer nesse ínterim: Já que eles estão faltando de qualquer maneira e eu realmente não tenho ou pelo menos "não deveria" ter tempo para fazer qualquer coisa além de suporte básico como este, seria muito apreciado se você pode enviar PRs para adicionar essas tipificações a ambos os projetos. 😊

@lhecker done :)

Só uma observação lateral, mas eu sempre recomendo usar PromiseLike para quando você aceitar promessas. Isso garantirá a interface de promessa mínima implementada para que você possa aceitar a maioria das promessas. Em seguida, você pode retornar o tipo de promessa de sua escolha, tornando-o mais rígido, como Bluebird<T> que tem muitos métodos extras. Por um longo tempo, nenhuma das minhas promessas foi atribuível por causa dos símbolos ES6 sendo adicionados aos tipos de promessa ES6.

@blakeembrey usando PromiseLike neste caso não é a resposta, porque PromiseLike também tem uma versão incompatível de então

Infelizmente, as tipificações da Promise mudaram na versão 2 do TS e, portanto, essas tipificações não correspondem mais: https://github.com/Microsoft/TypeScript/blob/070aa83cc06b2974639bbefcde98e6e2fb5fe693/src/lib/es2015.promise.d.ts

Podemos reabrir este problema?

Alguma atualização sobre isso?

@OliverJAsh @ arg20, vocês podem fornecer um caso de teste auto-reproduzível do seu problema?

@Strate aqui você tem meu erro. Usando o typescript 2.0.3 (lib.es6.d.ts) e @ 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>'.              

Tentar lançar a promessa do Bluebird para uma promessa ES6 gera o seguinte ( 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>'.         

adicionar isso conforme proposto em # 10831 funcionou para mim

readonly [Symbol.toStringTag]: 'Promise';

além disso, a conversão para uma Promessa ES6 funcionou

return new Promise.resolve(bluebirdPromise)

@jmendiara como declarado em # 10831, não há readonly [Symbol.toStringTag] no bluebird na verdade, então, adicionar isso ao bluebird.d.ts é definitivamente errado: a digitação deve representar o mundo real.
Se o padrão Promise exigir readonly [Symbol.toStringTag] , ele deve ser adicionado ao próprio bluebird e ao bluebird.d.ts também. Parece que você deve definitivamente usar a conversão entre bluebird e promessas nativas (o que é realmente irritante).
Para sua informação: você pode usar Promise.resolve sem a palavra-chave new .

Apenas tive problemas quando a promessa do bluebird não pode ser atribuída ao padrão. E no meu caso é impossível lançar o bluebird para o padrão com Promise.resolve , porque ele está profundamente em um objeto de terceiros. Então, às vezes é razoável ter a promessa do bluebird de ser atribuível ao padrão sem conversão.
Acabei de criar um pedido de recurso no repositório do bluebird, para adicionar Symbol.toStringTag às instâncias do bluebird.

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

Alguma atualização sobre isso?

Ainda bem que encontrei este tópico. Pensei que estava enlouquecendo. Realmente gostaria de ver uma solução para isso. Descrevi meus problemas específicos no SO

Estou tendo esse problema com @ types / bluebird 3.5.3 e TypeScript 2.2.2.

@silentorb Eu @types/bluebird-global e, em seguida, substituindo a definição de promessa global (que você terá se estiver visando uma plataforma ES2015), adicionando o seguinte no topo do meu código ponto de entrada de execução:

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

O acima funciona para o ambiente de nó (estou usando 6.10.x). Se você estiver usando o webpack , pode ser necessário usar algo como _expose-loader_.

@ksnyde : Eu já experimentei @types/bluebird-global e encontrei vários detalhes de Promessa ausentes. Eu considerei corrigir @types/bluebird-global mas seria melhor ter @types/bluebird funcionando.

@silentorb a chave é substituir a referência global da Promise; funciona sem problemas para mim. Dito isso, certamente seria bom se funcionasse imediatamente, mas não há necessidade de esperar com esta solução.

Algum progresso nisso?

Eu também estou tendo esse problema. Tudo se resume a erros como o seguinte:

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

Muito frustrante. Isso também está quebrando o uso de outros pacotes de digitação, como sequelize .

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

MissionModel terá o seguinte erro, a menos que Promise seja importado como * 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, você poderia reabrir o problema?
Pensando bem, vou apresentar um novo, mais direcionado.

Eu realmente odeio perder tempo para consertar esse tipo de problema de digitação. Porque o código é muito claro, mas para passar o tsc você tem que fazer mais trabalho extra. A maneira mais fácil de corrigir isso é criar uma variável temporária com o tipo any. Em seguida, converta-o em sua promessa de destino. Tal como:

'' '
const p: qualquer = getPromise ();
Retorna> p;
'' '

@flyingsky (et. al.) Em primeiro lugar, gostaria de lembrar a todos novamente que nunca será possível atribuir diretamente promessas nativas para Bluebirds, uma vez que as promessas Bluebird fornecem extensões que não existem na implementação nativa.

Atribuir promessas do Bluebird aos nativos, por outro lado, deve ser possível e com razão. Mas muitos aqui têm a impressão de que isso deve funcionar agora, o que definitivamente não é o caso.

A razão para isso é que, embora o Bluebird exponha todas as funções comumente conhecidas de uma maneira nativa compatível, ele _não_ expõe um campo em particular: O campo [Symbol.toStringTag] deve ser "promise" . Veja aqui: https://github.com/petkaantonov/bluebird/issues/1277. Isso torna o Bluebird estritamente visto como incompatível com as promessas nativas. Soo ...

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

Este é um tipo tecnicamente inseguro e incorreto.

Eu considerei corrigir @types/bluebird-global , mas seria melhor ter @types/bluebird funcionando.

bluebird-global atende a um caso de uso totalmente diferente do que bluebird : existe no caso de você seguir a rota insegura de sobrescrever a variável global Promise com Bluebird . (Não é seguro porque simplesmente substituí-lo não significa que todos os pacotes dos quais você depende não continuarão usando promessas nativas.)

Se alguém nesta edição quiser ver o progresso, sugiro a abertura de um PR para o problema do Bluebird já mencionado: https://github.com/petkaantonov/bluebird/issues/1277

Se alguém nesta edição quiser ver o progresso, sugiro a abertura de um PR para a questão do Bluebird já mencionada: petkaantonov / bluebird # 1277

Parece que este PR foi criado: https://github.com/petkaantonov/bluebird/pull/1421

@ksnyde - Sua @types/bluebird-global sugestão funciona para mim, ligeiramente modificada:

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

Caso contrário, recebo error TS6133: 'Promise' is declared but its value is never read. que é esperado para tsconfig.json com "noUnusedLocals": true .

Obrigada.

Estou usando bluebird-global mas ainda recebo este erro:

Propriedade '[Symbol.toStringTag]' ausente no tipo 'Bluebird'

Adicionar esta linha corrige o problema https://github.com/DefinitelyTyped/DefinitelyTyped/pull/10831/files

Existe alguma maneira de consertá-lo localmente sem modificar as tipificações do bluebird?

+1

@gdpaulmil Obrigado pelo seu comentário construtivo!

Isso me levou a dar uma olhada no estado das coisas na Bluebird.
Acontece que https://github.com/petkaantonov/bluebird/pull/1421 foi mesclado 11 dias atrás, o que significa que eles finalmente adicionaram suporte para Symbol.toStringTag ! 🎉

Isso, por sua vez, significa que o problema pode ser corrigido imediatamente, reenviando o nº 10831. Basta trocar "Promise" por "Object" . Eu honestamente revisaria imediatamente. 🙂

@lhecker , criou # 35353 para esclarecer tudo isso!

Ei, gostaria apenas de informar a todos que esse problema foi corrigido na v3.5.27 de @types/bluebird .
Agora você pode gostar de poder atribuir todos esses Bluebirds a todas essas Promessas. 🎉
Você terá que usar o TypeScript 3.2 ou mais recente para isso. (Veja # 34805)

PS: Obrigado novamente @JoshuaKGoldberg por lidar com a Bluebird PR. 🙂👍

É:

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

Ainda aplicável para es2017?

Exceto por todos os outros pacotes que têm a versão anterior como dependência e não receberam o memo ... pedido-promessa, knex, ... você acabou de quebrar muitos códigos com esta atualização. O compilador Typescript está jogando erros absurdos por todo o lugar, Typescript 3.3, 3.4, 3.5 ... não parece importar.

Se isso ajudar alguém, como mencionei mais acima, foi mais fácil apenas NÃO trocar meu objeto Promessa global por BB. Não encontrei nenhum problema em que uma coisa fosse compatível com outra.

@jacklinton Tenho certeza de que você já sabe que os testes de unidade estão em vigor para verificar se todos os pacotes afetados ainda são compilados com a versão do TypeScript fornecida sem "lançar erros sem sentido".
Por exemplo, aqui está um projeto que mostra solicitação-promessa trabalhando com as mais novas tipificações Bluebird: https://github.com/lhecker/request-promise-sample
Como não consigo reproduzir seu problema, seria incrível se você pudesse fornecer um exemplo mínimo que mostre os problemas que está vendo.

É difícil saber por onde começar, mas com todos os outros pacotes atualizados
Error:(19, 3) TS2741: Property '[Symbol.toStringTag]' is missing in type 'Bluebird<string[]>' but required in type 'Bluebird<string[]>'.
Se eu remover @ types / bluebird, esses erros desaparecerão. A única conjectura que posso fazer com o tempo que tenho é que nem todos os outros pacotes que precisam desses tipos foram atualizados ainda. Suspeito que Knex seja um provável culpado, mas não sei. Ele obtém sua própria dependência da versão anterior deste pacote.

Este erro soa como se você tivesse duas versões de @types/bluebird instaladas. Você deve tentar ver se consegue achatar aquela árvore para ter apenas uma delas.

O knex 0.17.3 depende da versão 3.5.27 mais recente das tipificações @types/bluebird aliás. Se você tiver uma versão atualizada do knex, ela deve funcionar, suponho.
O mesmo vale para sua segunda cópia de @types/bluebird : ela também deve ser 3.5.27.

Obrigado por ser responsivo @lhecker . Não quis parecer crítico, peço desculpas. Você claramente tem trabalhado muito nisso e é algo pelo qual esperamos muito tempo. Obrigado pelo seu trabalho árduo em lançar esta atualização tão rapidamente depois que o Bluebird fez a mudança. Vou fazer com que este monólito inchado funcione da maneira que deveria, de uma forma ou de outra.

@lhecker, você pode republicar sua amostra de solicitação de promessa porque ela parece ter sumido. 😢

@VictorioBerra o truque com

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

me dá o seguinte erro no Node.js 12:

global.Promise = Promessa;
O tipo 'typeof Bluebird' não contém as seguintes propriedades do tipo 'Function': apply, call, bind, length e 4 more.

Estou usando o TypeScript v3.7.4, bluebird v3.7.2 e @ types / bluebird-global v3.5.12.

@bennyn Não tenho mais o código. Eu sinto muito. Eu o excluí depois que o problema de solicitação-promessa foi corrigido.
Certifique-se de usar a versão mais recente de @types/bluebird em 3.5.29.

Estou tendo o mesmo erro que @bennyn , com as versões mais recentes de todos os bluebird, @ types / bluebird-global e TypeScript

Parece que a única opção viável com a versão atual do Bluebird 3.7.2 e TypeScript 3.6 é não usar nenhuma tipificação do Bluebird.

No ponto de entrada do aplicativo, substituo o construtor Promise nativo pelo Bluebird e uso o Bluebird usando a API de promessa nativa depois disso:

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

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

Eu pessoalmente, francamente, acredito que vocês estão fazendo algo errado do seu lado. 😖
Eu reconstruí meu projeto mínimo de request-promise-sample que mostra como você absolutamente 100% definitivamente pode ...

  • atribua o construtor Bluebird a global.Promise
  • usar promessa de solicitação sem erros de compilação
  • atribuir Bluebird instâncias de classe à interface Promise (que é sobre o que trata este problema)

_Dito isso, este problema foi encerrado e não deve ser usado para discussões contínuas fora do tópico._
A discussão acima está fora do tópico, já que este tíquete é sobre as promessas do Bluebird que não podem ser atribuídas ao ES6 / Native Promises. Mas, como mostrado acima, esse problema foi corrigido há muito tempo.
Se você tiver problemas para usar @types/[email protected] com o Bluebird, consulte https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42084 .

@lhecker
Obrigado pela resposta. Experimentei o seu projeto e também não funciona:
Annotation 2020-03-21 084422

Instalar @types/[email protected] também não ajuda:
Annotation 2020-03-21 084750

O projeto modificado pode ser encontrado aqui:
https://github.com/chebum/request-promise-sample

@chebum Seu comentário acima não deixou claro que você está tentando digitar funções assíncronas como se estivessem retornando Bluebird<T> . Nesse caso, eu já poderia ter dito que isso não é possível, infelizmente. Como você pode ver pela saída de seu compilador, você _deve_ retornar um tipo Promise<T> de uma função assíncrona.

Se quiser renunciar um pouco à sua segurança de tipo, você pode fazer o seguinte:

  1. Adicionar @types/bluebird-global como dependência
  2. Substitua o construtor global Promise: window.Promise = Bluebird as any;
  3. Escreva: async function testFn(): Promise<void>
  4. O tipo global Promise<T> agora é quase idêntico a Bluebird<T> e você deve ser capaz de usar todos os recursos importantes do Bluebird.

Se você encontrar qualquer Symbol.species erro etc. por favor _não_ use este tíquete, mas # 42084.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

demisx picture demisx  ·  3Comentários

jrmcdona picture jrmcdona  ·  3Comentários

victor-guoyu picture victor-guoyu  ·  3Comentários

variousauthors picture variousauthors  ·  3Comentários

jbreckmckye picture jbreckmckye  ·  3Comentários