Definitelytyped: Определение bluebird 3.0 не может быть присвоено обещаниям ES6

Созданный на 5 сент. 2016  ·  48Комментарии  ·  Источник: DefinitelyTyped/DefinitelyTyped

Определение bluebird 3.0 не может быть присвоено стандартному определению обещания es6:

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). Если вы используете веб-пакет, вам может потребоваться что-то вроде _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 . Добавление этой строки не помогает.

Ах , я вижу ... Я считаю , что из - за этой линии не хватает здесь . Это означает, что при текущих типах вы должны вернуть тот же тип U как из onFulfill так и из 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, но я даже не использую then или catch . У меня что-то вроде этого:

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

К сожалению, типизация Promise изменилась в TS версии 2, поэтому эти типы больше не соответствуют: https://github.com/Microsoft/TypeScript/blob/070aa83cc06b2974639bbefcde98e6e2fb5fe693/src/lib/es2015.promise.d.ts

Можем ли мы снова открыть эту проблему?

Есть обновления по этому поводу?

@OliverJAsh @ arg20 , ребята, не могли бы вы предоставить самовоспроизводимый тестовый пример вашей проблемы?

@Strate вот моя ошибка. Использование машинописного текста 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 выдается следующее ( 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, на самом деле в readonly [Symbol.toStringTag] , поэтому добавлять это в bluebird.d.ts определенно неправильно: типизация должна представлять реальный мир.
Если стандарт Promise требует readonly [Symbol.toStringTag] , его следует добавить как в bluebird, так и в bluebird.d.ts. Похоже, вам следует обязательно использовать преобразование между bluebird и родными обещаниями (что действительно раздражает).
К вашему сведению: вы можете использовать Promise.resolve без ключевого слова new .

Просто столкнулся с проблемой, когда обещание bluebird нельзя присвоить стандартному. И в моем случае невозможно привести bluebird к стандарту с помощью Promise.resolve , потому что это глубоко в стороннем объекте. Таким образом, иногда имеет смысл иметь обещание 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). Если вы используете веб-пакет, вам может потребоваться что-то вроде _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>;
}

MissionModel будет иметь следующую ошибку, если Promise будет импортирован как * 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, не могли бы вы повторно открыть проблему?
Если подумать, я просто запишу новый, более целевой.

Я действительно ненавижу тратить время на исправление такой проблемы с машинописным текстом. Поскольку код очень ясен, но для прохождения tsc вам нужно проделать больше дополнительной работы. Самый простой способ исправить это - создать временную переменную с типом any. Затем преобразуйте его в целевое обещание. Такие как:

'' '
const p: any = getPromise ();
возвращение> p;
'' '

@flyingsky (et. al.) Прежде всего, я хотел бы еще раз напомнить всем, что никогда не удастся напрямую назначить собственные обещания для Bluebird, поскольку обещания Bluebird предоставляют расширения, которых нет в исходной реализации.

С другой стороны, назначение обещаний Bluebird нативным должно быть возможным, и это правильно. Но многие здесь считают, что это должно работать прямо сейчас, что определенно не так.

Причина этого в том, что, хотя Bluebird предоставляет все широко известные функции совместимым образом, он _не_ раскрывает одно конкретное поле: поле [Symbol.toStringTag] должно быть "promise" . Смотрите здесь: https://github.com/petkaantonov/bluebird/issues/1277. Это делает Bluebird несовместимым с собственными обещаниями. Так ...

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

Это технически небезопасно и неверно.

Я подумал о том, чтобы исправить @types/bluebird-global , но было бы лучше, чтобы @types/bluebird работал.

bluebird-global выполняет совершенно другой вариант использования, чем bluebird : он существует на тот случай, если вы выберете очень небезопасный способ перезаписать глобальную переменную Promise с помощью Bluebird . (Это небезопасно, потому что простая перезапись не означает, что каждый пакет, от которого вы зависите, не будет продолжать использовать собственные обещания.)

Если кто-то в этом вопросе хочет увидеть прогресс, я предлагаю открыть PR для уже упомянутой проблемы Bluebird: https://github.com/petkaantonov/bluebird/issues/1277

Если кто-то в этом выпуске хочет увидеть прогресс, я предлагаю открыть PR для уже упомянутого выпуска Bluebird: petkaantonov / bluebird # 1277

Похоже, этот PR создан: https://github.com/petkaantonov/bluebird/pull/1421

@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 но все равно получаю эту ошибку:

Свойство «[Symbol.toStringTag]» отсутствует в типе «Bluebird».'

Добавление этой строки устраняет проблему https://github.com/DefinitiTyped/DefinentyTyped/pull/10831/files.

Есть ли способ исправить это локально, не изменяя набор текста bluebird?

+1

@gdpaulmil Спасибо за конструктивный комментарий!

Это побудило меня взглянуть на положение дел в Bluebird.
Оказывается, https://github.com/petkaantonov/bluebird/pull/1421 был объединен 11 дней назад, что означает, что они наконец добавили поддержку для Symbol.toStringTag ! 🎉

Это, в свою очередь, означает, что эту проблему можно решить сразу же, повторно отправив # 10831. Нужно будет только заменить "Promise" на "Object" . Честно говоря, я бы сразу просмотрел это. 🙂

@lhecker , создал # 35353, чтобы все прояснить!

Привет, я просто хотел бы сообщить вам, что эта проблема была исправлена ​​в версии 3.5.27 @types/bluebird .
Теперь вам может понравиться возможность назначить всех этих голубых птичек всем этим обещаниям. 🎉
Однако для этого вам придется использовать TypeScript 3.2 или новее. (См. №34805)

PS: Еще раз спасибо

Является:

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

Все еще актуально для es2017?

За исключением всех других пакетов, которые имеют предыдущую версию в качестве зависимости и не получили памятку ... запрос-обещание, knex, ... вы просто сломали много кода с этим обновлением. Компилятор Typescript выдает бессмысленные ошибки повсюду, Typescript 3.3, 3.4, 3.5 ... похоже, не имеет значения.

Если это кому-то поможет, как упоминалось выше, мне было легче всего просто НЕ менять местами мой глобальный объект Promise на BB. Я не сталкивался с проблемами, когда одно было совместимо с другим.

@jacklinton Я уверен, что вы уже знаете, что существуют модульные тесты для проверки того, что все затронутые пакеты по-прежнему собираются с данной версией TypeScript без «выдачи бессмысленных ошибок».
Например, вот проект, показывающий, как запрос-обещание работает с новейшими типами Bluebird: https://github.com/lhecker/request-promise-sample
Поскольку я не могу воспроизвести вашу проблему, было бы здорово, если бы вы могли предоставить минимальный пример, показывающий проблемы, которые вы видите.

Трудно понять, с чего начать, но все остальные пакеты обновлены
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 зависит от новейшей версии 3.5.27 @types/bluebird типов, кстати. Я полагаю, что если у вас есть последняя версия knex, она действительно должна работать.
То же самое касается вашей второй копии @types/bluebird хотя: она также должна быть 3.5.27.

Спасибо за отзывчивость @lhecker . Я не хотел казаться критичным, прошу прощения. Вы явно много работали над этим, и мы все так долго этого ждали. Спасибо за вашу тяжелую работу по быстрому выпуску этого обновления после того, как Bluebird внесла изменения. Я заставлю этот раздутый монолит работать так, как и положено, так или иначе.

@lhecker, не могли бы вы запрос-обещание-образец, потому что он, кажется, исчез. 😢

@VictorioBerra трюк с

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

дает мне следующую ошибку на Node.js 12:

global.Promise = Обещание;
В типе typeof Bluebird отсутствуют следующие свойства типа Function: применение, вызов, привязка, длина и еще 4.

Я использую TypeScript v3.7.4, bluebird v3.7.2 и @ types / bluebird-global v3.5.12.

@bennyn У меня больше нет кода. Мне очень жаль. Я удалил его после того, как проблема с запросом-обещанием была исправлена.
Убедитесь, что вы используете последнюю версию @types/bluebird 3.5.29.

У меня та же ошибка, что и у @bennyn , с последними версиями всех bluebird, @ types / bluebird-global и TypeScript

Кажется, что единственный жизнеспособный вариант с текущей версией Bluebird 3.7.2 и TypeScript 3.6 - это вообще не использовать типизацию Bluebird.

В точке входа в приложение я заменяю собственный конструктор Promise на Bluebird и использую Bluebird, используя собственный API обещаний после этого:

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
  • использовать запрос-обещание без ошибок компиляции
  • правопреемник Bluebird экземпляров класса к Promise интерфейса (что этот вопрос о)

_Тем не менее, этот вопрос был закрыт, и его не следует использовать для продолжения дискуссий, не относящихся к теме. _
Вышеупомянутое обсуждение не по теме, поскольку этот билет касается обещаний Bluebird, которые нельзя назначать ES6 / родным обещаниям. Но, как показано выше, эта проблема давно исправлена.
Если у вас возникли проблемы с использованием @types/[email protected] с Bluebird, см. Https://github.com/DefinitiTyped/DefinitiTyped/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. Переопределить глобальный конструктор обещаний: window.Promise = Bluebird as any;
  3. Напишите: async function testFn(): Promise<void>
  4. Глобальный тип Promise<T> теперь почти идентичен типу Bluebird<T> и вы должны иметь возможность использовать все важные функции Bluebird.

Если вы столкнетесь с какими-либо ошибками Symbol.species и т. Д., Пожалуйста, _не_ используйте этот билет, а лучше # 42084.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги