[英]Union type for generic param
代理返回條件隨機類型。
const numbersArray = [1,2,3,4];
const stringsArray = ['1','2','3','4'];
function func<T>(array: T[]): T[][] {
return [[array[0], array[1]], [array[2], array[3]]];
}
const proxy = () => Math.random() < 0.5 ? numbersArray : stringsArray;
const resulNumbers = func(numbersArray);
const resultStrings = func(stringsArray);
const resultUnion = func(proxy()); // error
錯誤
const proxy: () => number[] | string[]
Argument of type 'number[] | string[]' is not assignable to parameter of type 'number[]'.
Type 'string[]' is not assignable to type 'number[]'.
Type 'string' is not assignable to type 'number'.(2345)
解決這個問題的正確方法,有什么想法嗎?
這個 function:
const proxy = () => Math.random() < 0.5 ? numbersArray : stringsArray;
返回類型為:
number[] | string[]
這種類型表示您要么有一個所有數字的數組,要么有一個所有字符串的數組,但絕不是兩者的混合。
那么該類型的成員的類型是什么? 你可能認為它是number | string
number | string
,但這並不完全正確。 如果你拿string | number
string | number
並將數組符號添加到末尾,您將獲得:
(number | string)[]
這種類型表示它是一個字符串或數字數組,每個成員都可以是。 您現在可以將兩者混合使用。 這不是一回事。 這意味着無法推斷成員類型,因為該成員類型不能用於構造原始數組類型。
現在讓我們看看通用的 function:
function func<T>(array: T[]): T[][] {
return [[array[0], array[1]], [array[2], array[3]]];
}
這個 function 試圖找到數組T[]
的成員類型T
。 但如上所示, string[] | number[]
沒有好的成員類型。 string[] | number[]
。 所以 typescript 無法推斷T
並拋出錯誤。
因此,要使您的 function 工作,成員類型T
需要是可推斷的。 您可以通過將代理的返回類型轉換為兼容的數組類型來做到這一點,其中只有數組的成員是聯合。
const proxy: () => (string | number)[] =
() => Math.random() < 0.5 ? numbersArray : stringsArray;
現在T
可以變成string | number
string | number
和一切都像你期望的那樣工作。
const resultUnion = func(proxy()); // type: (string | number)[][]
發生錯誤是因為類型參數T
如何解析對func
的調用。 proxy
的返回類型是
number[] | string[]
並根據number[] | string[]
的方式推斷T
的類型 number[] | string[]
符合以下簽名:
function func<T>(x: T[]): T[][]
所以x
必須是T
的數組,就func
而言,它可以是任何類型。 在number[] | string[]
的情況下 number[] | string[]
T
的類型被推斷為number
,因為number[]
是聯合中第一個與x
的T[]
匹配的類型。 不幸的是,沒有考慮到string[]
。
您可能希望T
是number | string
此調用的number | string
,您可以通過在調用func
時顯式指定類型來做到這一點:
const xs: (number | string)[][] = func<number | string>(proxy())
這個重復的問題的答案解釋了為什么 TypeScript 並不總是推斷泛型類型參數的聯合; 這是因為當調用者為單個泛型類型參數指定多個事物時,它通常表示錯誤,並且如果編譯器總是在這種情況下推斷出一個聯合,它將允許很多可能錯誤的代碼。 有關此問題的“官方”討論,請參見microsoft/TypeScript#19656 。
無論如何,在您的情況下,我可能會將func()
簽名更改為:
function func<T extends any[]>(array: T): T[number][][] {
return [[array[0], array[1]], [array[2], array[3]]];
}
在這種情況下, T
實際上是傳入數組的類型,而不是其成員的類型,即T[number]
。 我想這應該對你有用。
希望有幫助; 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.