Definitelytyped: definisi bluebird 3.0 tidak dapat ditetapkan ke ES6 Promises

Dibuat pada 5 Sep 2016  ·  48Komentar  ·  Sumber: DefinitelyTyped/DefinitelyTyped

Definisi bluebird 3.0 tidak dapat ditetapkan ke definisi standar es6 Promise:

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

/cc @lhecker

Komentar yang paling membantu

@silentorb Saya telah membuat ini berfungsi dengan menggunakan definisi tipe @types/bluebird-global dan kemudian mengganti definisi janji global (yang akan Anda miliki jika Anda menargetkan platform ES2015) dengan menambahkan yang berikut ini ke bagian atas kode saya titik masuk eksekusi:

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

Di atas berfungsi untuk lingkungan simpul (saya menggunakan 6.10.x). Jika Anda menggunakan webpack maka Anda mungkin perlu menggunakan sesuatu seperti _expose-loader_.

Semua 48 komentar

@Strate Bisakah Anda memposting sisa keluaran tsc? Dan coba buka bluebird.d.ts dan tambahkan satu baris ini dari #10831 . Apakah itu memperbaiki masalah Anda?

Seluruh kesalahan:

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

Saya menggunakan [email protected] dengan file lib.es2016.d.ts . Menambahkan baris itu tidak membantu.

Ah begitu... Saya percaya itu karena garis ini hilang di sini . Ini berarti dengan pengetikan saat ini Anda harus mengembalikan tipe yang sama U dari onFulfill maupun onReject . Akan sangat keren jika seseorang dapat memperbaikinya di npm dan repositori dt ini btw.

Sementara itu Anda mungkin harus membagi .then(success, failure) menjadi .then(success).catch(failure) karena mungkin itu yang Anda lakukan dengan benar? Meskipun itu adalah bagian dari sintaks resmi, itu benar-benar bukan yang "lebih disukai" dengan bluebird.

Alternatifnya adalah Anda dapat secara manual menentukan parameter generik U seperti ini

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

untuk memastikan bahwa Anda mengembalikan jenis yang sama dari kedua panggilan balik.

@lhecker tapi saya bahkan tidak menggunakan then atau catch . Saya memiliki sesuatu seperti itu:

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

Tampaknya itu bisa diperbaiki dengan menambahkan lagi deklarasi then , kompatibel dengan es6 ke bluebird.d.ts

Ah sial... maaf. Kurasa aku akhirnya harus istirahat. 😅

Jadi abaikan komentar saya tentang apa yang harus dilakukan sementara itu: Karena mereka hilang dan karena saya benar-benar tidak atau setidaknya "tidak boleh" punya waktu untuk melakukan apa pun selain dukungan dasar seperti ini, akan sangat dihargai jika Anda dapat mengirim PR untuk menambahkan pengetikan tersebut ke kedua proyek. 😊

@lhecker selesai :)

Sekadar catatan, tapi saya selalu merekomendasikan menggunakan PromiseLike ketika Anda menerima janji. Ini akan menjamin antarmuka janji minimum yang diterapkan sehingga Anda dapat menerima sebagian besar janji. Kemudian Anda dapat mengembalikan jenis janji pilihan Anda, membuatnya lebih ketat seperti Bluebird<T> yang memiliki banyak metode tambahan. Untuk waktu yang lama, tidak ada janji saya yang dapat dialihkan karena simbol ES6 ditambahkan ke tipe janji ES6.

@blakeembrey menggunakan PromiseLike dalam hal ini bukan jawabannya, karena PromiseLike juga memiliki versi yang tidak kompatibel saat itu

Sayangnya pengetikan Janji telah berubah di TS versi 2 dan pengetikan ini tidak lagi sesuai: https://github.com/Microsoft/TypeScript/blob/070aa83cc06b2974639bbefcde98e6e2fb5fe693/src/lib/es2015.promise.d.ts

Bisakah kita membuka kembali masalah ini?

Ada pembaruan tentang ini?

@OliverJAsh @arg20 bisakah kalian memberikan kasus uji yang dapat direproduksi sendiri dari masalah Anda?

@Strate di sini Anda memiliki kesalahan saya. Menggunakan TypeScript 2.0.3 (lib.es6.d.ts) dan @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>'.              

Mencoba untuk memberikan Janji Bluebird ke janji ES6 melempar yang berikut ( 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>'.         

menambahkan ini seperti yang diusulkan di # 10831 berhasil untuk saya

readonly [Symbol.toStringTag]: 'Promise';

juga, mengonversi ke ES6 Promise berhasil

return new Promise.resolve(bluebirdPromise)

@jmendiara seperti yang dinyatakan dalam #10831, sebenarnya tidak ada readonly [Symbol.toStringTag] di bluebird, jadi, menambahkan ini ke bluebird.d.ts jelas salah: pengetikan harus mewakili dunia nyata.
Jika standar Promise memerlukan readonly [Symbol.toStringTag] , itu harus ditambahkan ke bluebird itu sendiri dan juga bluebird.d.ts. Tampaknya Anda harus benar-benar menggunakan konversi antara bluebird dan janji asli (yang benar-benar menjengkelkan).
FYI: Anda dapat menggunakan Promise.resolve tanpa kata kunci new .

Baru saja mengalami masalah ketika janji bluebird tidak dapat dialihkan ke yang standar. Dan dalam kasus saya tidak mungkin untuk melemparkan bluebird ke standar dengan Promise.resolve , karena jauh di dalam objek pihak ke-3. Jadi, terkadang masuk akal jika janji bluebird dapat dialihkan ke yang standar tanpa konversi.
Baru saja membuat permintaan fitur di repositori bluebird, untuk menambahkan Symbol.toStringTag ke instance bluebird.

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

Ada pembaruan tentang ini?

Senang saya menemukan utas ini. Pikir saya akan gila. Sangat ingin melihat perbaikan untuk ini. Saya menjelaskan masalah saya secara spesifik di SO

Saya mengalami masalah ini dengan @types/bluebird 3.5.3 dan TypeScript 2.2.2.

@silentorb Saya telah membuat ini berfungsi dengan menggunakan definisi tipe @types/bluebird-global dan kemudian mengganti definisi janji global (yang akan Anda miliki jika Anda menargetkan platform ES2015) dengan menambahkan yang berikut ini ke bagian atas kode saya titik masuk eksekusi:

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

Di atas berfungsi untuk lingkungan simpul (saya menggunakan 6.10.x). Jika Anda menggunakan webpack maka Anda mungkin perlu menggunakan sesuatu seperti _expose-loader_.

@ksnyde : Saya sebelumnya mencoba @types/bluebird-global dan mengalami beberapa detail Janji yang hilang. Saya mempertimbangkan untuk menambal @types/bluebird-global tetapi akan lebih baik jika @types/bluebird berfungsi.

@silentorb kuncinya adalah mengganti referensi Janji global; bekerja tanpa masalah bagi saya. Yang mengatakan, tentu akan menyenangkan jika itu berhasil tetapi tidak perlu menunggu dengan solusi ini.

Ada kemajuan dalam hal ini?

Saya juga mendapatkan masalah ini. Itu bermuara pada kesalahan seperti berikut:

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

Sangat membuat frustrasi. Ini juga melanggar penggunaan paket pengetikan lainnya, seperti sequelize .

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

MissionModel akan memiliki kesalahan berikut kecuali Promise diimpor sebagai * 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 bisakah Anda membuka kembali masalah ini?
Setelah dipikir-pikir, saya hanya akan mengajukan yang baru, lebih bertarget.

Saya sangat benci membuang waktu untuk memperbaiki masalah TypeScript semacam ini. Karena kodenya sangat jelas, tetapi untuk lulus tsc Anda harus melakukan lebih banyak pekerjaan ekstra. Cara mudah saya memperbaikinya adalah membuat variabel temp dengan tipe any. Kemudian konversikan ke Janji target Anda. Seperti:

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

@flyingsky (et. al.) Pertama-tama saya ingin mengingatkan semua orang lagi bahwa tidak akan pernah mungkin untuk secara langsung menetapkan Janji asli ke Bluebird, karena janji Bluebird menyediakan ekstensi yang tidak ada dalam implementasi asli.

Menugaskan janji Bluebird kepada yang asli di sisi lain harus dimungkinkan dan memang demikian. Tetapi banyak orang di sini mendapat kesan bahwa ini seharusnya bekerja sekarang, yang sebenarnya tidak demikian.

Alasan untuk ini adalah bahwa sementara Bluebird mengekspos semua fungsi yang umum dikenal dengan cara asli yang kompatibel, itu _tidak_ mengekspos satu bidang tertentu: Bidang [Symbol.toStringTag] harus "promise" . Lihat di sini: https://github.com/petkaantonov/bluebird/issues/1277. Ini membuat Bluebird benar-benar terlihat tidak sesuai dengan janji asli. Su...

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

Ini secara teknis ketik tidak aman dan salah.

Saya mempertimbangkan untuk menambal @types/bluebird-global , tetapi akan lebih baik jika @types/bluebird berfungsi.

bluebird-global menyajikan kasus penggunaan yang sama sekali berbeda dari yang dilakukan bluebird : Itu ada jika Anda menggunakan banyak jenis rute yang tidak aman untuk menimpa variabel global Promise dengan Bluebird . (Ini tidak aman karena hanya menimpanya tidak berarti bahwa setiap paket yang Anda andalkan tidak akan terus menggunakan janji asli.)

Jika ada orang dalam masalah ini yang ingin melihat kemajuan, saya sarankan membuka PR untuk masalah Bluebird yang telah disebutkan: https://github.com/petkaantonov/bluebird/issues/1277

Jika ada orang dalam masalah ini yang ingin melihat kemajuan, saya sarankan membuka PR untuk masalah Bluebird yang telah disebutkan: petkaantonov/bluebird#1277

Sepertinya PR ini telah dibuat: https://github.com/petkaantonov/bluebird/pull/1421

@ksnyde@types/bluebird-global berfungsi untuk saya, sedikit dimodifikasi:

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

Kalau tidak, saya mendapatkan error TS6133: 'Promise' is declared but its value is never read. Yang diharapkan untuk tsconfig.json dengan "noUnusedLocals": true .

Terima kasih.

Saya menggunakan bluebird-global tetapi masih mendapatkan kesalahan ini:

Properti '[Symbol.toStringTag]' tidak ada dalam jenis 'Bluebird'

Menambahkan baris ini memperbaiki masalah https://github.com/DefinitelyTyped/DefinitelyTyped/pull/10831/files

Apakah ada cara untuk memperbaikinya secara lokal tanpa mengubah pengetikan bluebird?

+1

@gdpaulmil Terima kasih atas komentar konstruktif Anda!

Itu mendorong saya untuk melihat keadaan di Bluebird.
Ternyata https://github.com/petkaantonov/bluebird/pull/1421 digabungkan 11 hari yang lalu, artinya mereka akhirnya menambahkan dukungan untuk Symbol.toStringTag ! 🎉

Artinya, masalah ini dapat segera diperbaiki dengan mengirimkan ulang #10831. Seseorang hanya perlu menukar "Promise" dengan "Object" . Saya akan segera meninjaunya dengan jujur. 🙂

@lhecker , dibuat #35353 untuk menyelesaikan ini semua!

Hai, saya hanya ingin memberi tahu Anda semua bahwa masalah ini telah diperbaiki di v3.5.27 dari @types/bluebird .
Anda sekarang dapat menikmati dapat menetapkan semua Bluebirds ini ke semua Janji ini. 🎉
Anda harus menggunakan TypeScript 3.2 atau yang lebih baru untuk ini. (Lihat #34805)

PS: Sekali lagi terima kasih @JoshuaKGoldberg karena berurusan dengan PR Bluebird. 👍

Adalah:

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

Masih berlaku untuk es2017?

Kecuali untuk semua paket lain yang memiliki versi sebelumnya sebagai ketergantungan dan tidak mendapatkan memo... request-promise, knex,... Anda baru saja memecahkan banyak kode dengan pembaruan ini. Kompiler TypeScript melemparkan kesalahan omong kosong di semua tempat, TypeScript 3.3, 3.4, 3.5... sepertinya tidak masalah.

Jika itu membantu siapa pun, seperti yang disebutkan lebih tinggi, saya memiliki waktu termudah hanya TIDAK menukar objek Janji global saya untuk BB. Saya belum menemukan masalah di mana satu hal kompatibel dengan hal lain.

@jacklinton Saya yakin Anda sudah mengetahui bahwa pengujian unit dilakukan untuk memverifikasi bahwa semua paket yang terpengaruh masih dibangun dengan versi TypeScript yang diberikan tanpa "melempar kesalahan yang tidak masuk akal".
Misalnya, inilah proyek yang menunjukkan permintaan-janji yang bekerja dengan pengetikan Bluebird terbaru: https://github.com/lhecker/request-promise-sample
Karena saya tidak dapat mereproduksi masalah Anda, akan luar biasa jika Anda dapat memberikan contoh minimal yang menunjukkan masalah yang Anda lihat.

Sulit untuk mengetahui dari mana harus memulai, tetapi dengan semua paket lain yang terbaru
Error:(19, 3) TS2741: Property '[Symbol.toStringTag]' is missing in type 'Bluebird<string[]>' but required in type 'Bluebird<string[]>'.
Jika saya menghapus @types/bluebird kesalahan ini hilang. Satu-satunya dugaan yang dapat saya buat dengan waktu yang saya miliki adalah bahwa tidak semua paket lain yang membutuhkan jenis ini telah menyusul. Saya menduga Knex adalah pelakunya, tapi saya tidak tahu. Itu mengambil ketergantungannya sendiri dari versi sebelumnya dari paket ini.

Kesalahan ini terdengar seolah-olah Anda menginstal dua versi @types/bluebird . Anda harus mencoba dan melihat apakah Anda dapat meratakan pohon itu sehingga Anda hanya memiliki salah satunya.

knex 0.17.3 bergantung pada versi 3.5.27 terbaru dari pengetikan @types/bluebird btw. Jika Anda memiliki versi knex yang terbaru, saya kira itu akan benar-benar berfungsi.
Hal yang sama berlaku untuk salinan kedua Anda dari @types/bluebird : Seharusnya juga 3.5.27.

Terima kasih sudah responsif @lhecker . Saya tidak bermaksud untuk terdengar kritis, saya minta maaf. Anda jelas telah bekerja keras untuk ini dan ini adalah sesuatu yang sudah lama kita semua tunggu. Terima kasih atas kerja keras Anda mengeluarkan pembaruan ini begitu cepat setelah Bluebird membuat perubahan. Saya akan membuat monolit yang membengkak ini bekerja dengan cara yang seharusnya.

@lhecker bisakah Anda mempublikasikan ulang contoh permintaan-janji Anda karena sepertinya sudah hilang. 😢

@VictorioBerra triknya dengan

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

memberi saya kesalahan berikut pada Node.js 12:

global.Janji = Janji;
Jenis 'typeof Bluebird' tidak memiliki properti berikut dari jenis 'Function': apply, call, bind, length, dan 4 lainnya.

Saya menggunakan TypeScript v3.7.4, bluebird v3.7.2 dan @types/bluebird-global v3.5.12.

@bennyn Saya tidak punya kode lagi. Aku sangat menyesal. Saya menghapusnya setelah masalah permintaan-janji diperbaiki.
Pastikan Anda menggunakan @types/bluebird versi terbaru pada 3.5.29.

Saya mengalami kesalahan yang sama dengan @bennyn , dengan versi terbaru dari semua bluebird, @types/bluebird-global dan TypeScript

Tampaknya satu-satunya opsi yang layak dengan versi Bluebird 3.7.2 dan TypeScript 3.6 saat ini adalah tidak menggunakan pengetikan Bluebird sama sekali.

Di titik masuk aplikasi saya mengganti konstruktor Promise asli dengan Bluebird dan menggunakan Bluebird menggunakan API janji asli setelah itu:

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

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

Saya pribadi, terus terang, percaya bahwa kalian melakukan sesuatu yang salah di pihak Anda. 😖
Saya telah merekonstruksi proyek minimal request-promise-sample yang menunjukkan bagaimana Anda benar-benar 100% pasti bisa...

  • tetapkan konstruktor Bluebird ke global.Promise
  • gunakan request-promise tanpa kesalahan kompilasi
  • menetapkan Bluebird contoh kelas ke Promise antarmuka (yang adalah apa masalah ini adalah tentang)

_Dengan demikian, masalah ini telah ditutup dan tidak boleh digunakan untuk melanjutkan diskusi di luar topik._
Diskusi di atas di luar topik, karena tiket ini tentang janji Bluebird yang tidak dapat dialihkan ke ES6/Janji asli. Tetapi seperti yang ditunjukkan di atas, masalah ini telah lama diperbaiki.
Jika Anda kesulitan menggunakan @types/[email protected] dengan Bluebird, silakan lihat https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42084 .

@lhecker
Terima kasih atas balasannya. Saya mencoba proyek Anda dan itu juga tidak berhasil:
Annotation 2020-03-21 084422

Menginstal @types/[email protected] juga tidak membantu:
Annotation 2020-03-21 084750

Proyek yang dimodifikasi dapat ditemukan di sini:
https://github.com/chebum/request-promise-sample

@chebum Komentar Anda di atas tidak menjelaskan bahwa Anda mencoba mengetik fungsi async sebagai yang mengembalikan Bluebird<T> . Dalam hal ini saya sudah bisa memberitahu Anda bahwa ini tidak mungkin sayangnya. Seperti yang Anda lihat dari keluaran kompiler Anda, Anda _harus_ mengembalikan tipe Promise<T> dari fungsi async.

Jika Anda ingin mengabaikan sedikit keamanan tipe Anda, Anda dapat melakukan hal berikut:

  1. Tambahkan @types/bluebird-global sebagai ketergantungan
  2. Ganti konstruktor Promise global: window.Promise = Bluebird as any;
  3. Tulis: async function testFn(): Promise<void>
  4. Tipe global Promise<T> sekarang hampir identik dengan Bluebird<T> dan Anda seharusnya dapat menggunakan semua fitur penting Bluebird.

Jika Anda menemukan kesalahan Symbol.species dll. harap _jangan_ gunakan tiket ini melainkan #42084.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat