Saya mencoba membuat *-as-promised versi dari async pustaka di TypeScript, menggunakan kembali @types/async jenis.

Masalah saya adalah @types/async di .filter function mengekspor dua jenis fungsi dengan nama yang sama:

export function filter<T, E>(arr: T[] | IterableIterator<T>, iterator: AsyncBooleanIterator<T, E>, callback?: AsyncResultArrayCallback<T, E>): void;
export function filter<T, E>(arr: Dictionary<T>, iterator: AsyncBooleanIterator<T, E>, callback?: AsyncResultArrayCallback<T, E>): void;

Tapi saya hanya mengekspor satu fungsi .filter :

function filter<T>(
    arr: async.Dictionary<T> | T[] | IterableIterator<T>,
    iterator: (item: T) => Promise<boolean>
  ): Promise<Array<(T | undefined)> | undefined> {
  return new Promise((resolve, reject) => {
    async.filter(arr, (item, cb) => {
      iterator(item)
        .then(res => cb(undefined, res))
        .catch(err => cb(err));
    }, (err, results) =>
      err
      ? reject(err)
      : resolve(results)
    );
  });
}

Saat mengkompilasi, ini memberi saya kesalahan berikut:

lib/filter.ts(32,18): error TS2345: Argument of type 'Dictionary<T> | IterableIterator<T> | T[]' is not assignable to parameter of type 'Dictionary<T>'.
  Type 'IterableIterator<T>' is not assignable to type 'Dictionary<T>'.

Jadi, Bagaimana saya bisa menggabungkan deklarasi itu hanya dalam satu?

Terimakasih.

0
Daniel Ramos 14 Oktober 2017, 19:29

1 menjawab

Jawaban Terbaik

Aneh bahwa pengetikan bukan merupakan tanda tangan fungsi tunggal dengan gabungan dari tiga kemungkinan jenis untuk parameter arr. Anda mungkin ingin mempertimbangkan untuk mengajukan masalah atau permintaan tarik ke pustaka pengetikan async untuk memperbaikinya.

Meski begitu, alangkah baiknya jika kompiler mengizinkan Anda memanggil fungsi seperti yang Anda miliki, karena Anda tahu aman untuk melakukannya. Tapi seperti yang Anda lihat, tidak akan, setidaknya pada TypeScript v2.5 .

Solusi termudah: karena Anda tahu pasti apa yang tidak diketahui oleh kompiler... yaitu, bahwa fungsi filter yang ada memang akan menerima arr tipe T[] | IterableIterator<T> | Dictionary<T>, itu adalah aman untuk memberi tahu kompiler agar tidak khawatir dengan menyatakan arr bertipe any yang menonaktifkan pemeriksaan tipe:

function filter<T>(
    arr: async.Dictionary<T> | T[] | IterableIterator<T>,
    iterator: (item: T) => Promise<boolean>
  ): Promise<Array<(T | undefined)> | undefined> {
  return new Promise((resolve, reject) => {
    async.filter(arr as any, (item, cb) => {
      iterator(item)
        .then(res => cb(undefined, res))
        .catch(err => cb(err));
    }, (err, results) =>
      err
      ? reject(err)
      : resolve(results)
    );
  });
}

Ada solusi lain, seperti menulis pengguna -defined type guarduntuk membagi panggilan ke async.filter() menjadi dua panggilan tergantung pada jenis arr; atau bungkus fungsi async.filter dengan sesuatu yang mirip dengan intersectFunction() sehingga menerima penyatuan yang Anda inginkan, tetapi solusi ini lebih besar dan memiliki efek runtime, jadi saya akan tetap menggunakan metode as any di atas.

Semoga membantu; Semoga beruntung!

1
jcalz 14 Oktober 2017, 20:43