我想創建一個通用的多維映射型別,其中 N 個型別中的最后一個是最終值,而前面的型別將有效地成為鍵。
換一種說法:
let m:MDMap<Coat,Pie,Date,Location>;
//...
m.get(myWoolCoat,myApplePie,yesterday) // returns a Location
沒有可變引數泛型雖然看起來我最終會得到這樣的東西:
export type MultiMap<
A extends any,
B extends any,
C = void,
D = void,
// ... etc.
> = D extends void
? C extends void
? Map<A,B>
: Map<A,Map<B,C>>
: Map<A,Map<B,Map<C,D>>>
let m:MultiMap<Coat,Pie,Date,Location>;
我知道 Typescript 處理可變元組型別,但我無法將這種能力與類似上述愿望的東西聯系起來。
我應該解決這個問題還是有什么方法可以實作某種遞回泛型?
uj5u.com熱心網友回復:
TypeScript 沒有可變引數泛型,所以沒有辦法寫出這樣的MultiMap<...K, V>意思,即存在任意數量的鍵型別引數和一個值型別引數。但是,正如您所注意到的,有些元 組型別MultiMap<K, V>可以保存任意有序的型別串列,因此您可能會對元組的位置感到滿意K。所以,而不是MultiMap<Coat, Pie, Date, Location>你會寫MultiMap<[Coat, Pie, Date], Location>. 反正就是多了幾個字符。
至于MultiMap<[Coat, Pie, Date], Location>決議到Map<Coat, Map<Pie, Map<Date, Location>>>,我們可以通過定義遞回條件型別來做到這一點MultiMap<K, V>,我們使用可變元組型別將K元組分解為它的第一個元素F和元組的其余部分R:
type MultiMap<K extends any[], V> = K extends [infer F, ...infer R] ?
Map<F, MultiMap<R, V>> : V;
這種語法K extends [infer F, ...infer R] ? XXX : YYY被稱為條件型別推斷,我們可以通過讓編譯器推斷新型別引數來將它們帶入作用域。 K extends [infer F, ...infer R] ? XXX : YYY意味著我們希望編譯器嘗試匹配K具有一些初始元素F和一些剩余元素的可變引數元組R。如果它有效,那么在XXX型別運算式中,F將是第一個元素型別,并且R將是代表其余元素的較短元組。也就是說,if Kis [Coat, Pie, Date]then Fwill beCoat和Rwill be [Pie, Date]。因此Map<F, MultiMap<R, V>>將是Map<Coat, MultiMap<[Pie, Date], V>>,您可以看到遞回發生。如果K是一個空元組,那么我們根本沒有鍵,我們只是使用V,以便遞回的基本情況以我們想要的方式終止。
讓我們確保它有效:
type MyMap = MultiMap<[Coat, Pie, Date], Location>;
// type MyMap = Map<Coat, Map<Pie, Map<Date, Location>>>
看起來不錯!
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/433062.html
