假設我有一些功能,例如:
function allPromises<T>(array: Promise<T>[]): Promise<T[]> {
return Promise.all(array);
}
(注意:這是故意設計成最小可重復性的)
如果我這樣做,它作業正常:
const p1: Promise<string> = new Promise((resolve) => resolve('1'));
const p2: Promise<string> = new Promise((resolve) => resolve('2'));
const test1 = [p1, p2];
const res1 = allPromises(test1);
沒有型別錯誤,并且res1正確鍵入為Promise<string[]>;
但如果我這樣做:
const p1: Promise<string> = new Promise((resolve) => resolve('1'));
const p2: Promise<number> = new Promise((resolve) => resolve(2));
const test2 = [p1, p2];
const res2 = allPromises(test2);
現在我收到一個 TS 投訴:
'(Promise<string> | Promise<number>)[]' 型別的引數不能分配給 'Promise<string>[]' 型別的引數。
似乎是因為test2輸入為(Promise<number> | Promise<string>)[]
我可以通過這樣做來解決這個問題:
const test2: Promise<string | number>[] = [p1, p2];
然后res2正確鍵入為Promise<(string | number)[]>
但是有沒有辦法鍵入我的函式,以便它可以正確推斷型別而不強迫我以這種方式顯式宣告陣列的型別?
注意:我也嘗試過多載類似于Promise.all鍵入方式的函式,但它也失敗了,并且要求我顯式鍵入陣列以讓 TS 接受它:
function allPromises<T1, T2>(array: [Promise<T1>, Promise<T2>]): Promise<[T1, T2]>
function allPromises<T>(array: Promise<T>[]): Promise<T[]>
function allPromises(array: Promise<unknown>[]): Promise<unknown[]> {
return Promise.all(array);
}
而且這種多載也無濟于事:
function allPromises<T1, T2>(array: (Promise<T1> | Promise<T2>)[]): Promise<(T1 | T2)[]>
而且我希望在 TS V3 中進行這項作業......我看到 V4.5 中的一些新型別可能對此有用,但我暫時停留在 V3 中。
uj5u.com熱心網友回復:
我讓它作業
type UnwrapPromiseArr<T> = T extends Promise<infer R>[]
? Promise<R[]>
: never;
function allPromises<T extends Promise<unknown>[]>(array: T): UnwrapPromiseArr<T> {
return Promise.all(array) as UnwrapPromiseArr<T>;
}
他們的關鍵是推斷最初來自內部陣列的聯合型別。
操場
uj5u.com熱心網友回復:
您的函式只是在做與 相同的事情Promise.all,所以只需將其定義為別名并將出色的輸入推遲到原始函式的:
const allPromises = Promise.all;
const p1: Promise<string> = new Promise((resolve) => resolve('1'));
const p2: Promise<number> = new Promise((resolve) => resolve(2));
const test2 = [p1, p2];
const res2 = allPromises(test2);
TypeScript Playground 鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442526.html
標籤:打字稿
上一篇:如何將引數傳遞給守衛?
