我想定義一個型別,如:
declare type TheOneMillionDollarType<
Entry extends [string, any],
TrMap extends [Entry[1], any]
> = /* TODO */unknown;
這樣,這里:
type Input = [ "foo", string ] | [ "bar", number ];
type TrMap = [ string, "string !" ] | [ number, "number !" ];
type Expected = [ "foo", "string !" ] | [ "bar", "number !" ];
type Got = TheOneMillionDollarType<Input, TrMap>;
Expected并且Got將是相同的型別。
很具體。我想編譯這個游樂場的代碼。
uj5u.com熱心網友回復:
一種方法是這樣定義它:
type TheOneMillionDollarType<
E extends [string, any],
M extends [E[1], any]
> = E extends unknown ? [E[0], Extract<M, [E[1], any]>[1]] : never;
該型別E extends unknown ? ... : never看起來像一個無操作,但它實際上是一個分配條件型別,它分裂E成它的聯合成員,評估...每個成員的部分,然后聯合(聯合?聯合?統一?無論如何)最后將結果重新組合在一起。
該型別是[E[0], Extract<M, [E[1], any]>[1]],您想要的元組型別,其中第一個元素與 的第一個元素相同E。第二元件使用的Extract<T, U>實用程式型別來過濾M聯合和找到任何構件(S)分配給[E[1], any]。這意味著我們正在選擇M第一個元素可分配給 的第二個元素的任何成員E。一旦我們得到它,我們就對它進行索引 ( [1]) 以獲得它的第二個元素。
這至少適用于您的示例:
type Got = TheOneMillionDollarType<Input, TrMap>;
// type Got = ["foo", "string !"] | ["bar", "number !"]
請注意,可能有很多邊緣情況:
type Hmm = TheOneMillionDollarType<["foo", string | number], [string, "a"]>
// type Hmm = ["foo", "a"]
type AlsoHmm = TheOneMillionDollarType<["foo", number], [0, "z"] | [1, "y"]>
// type AlsoHmm = ["foo", "z" | "y"]
type ThirdHmm = TheOneMillionDollarType<["foo", string] | ["bar", number], [string | number, "a"]>;
// type ThirdHmm = ["foo", never] | ["bar", never]
打賭第三個不是你想要的,但也許你不關心那個邊緣情況。無論如何,我建議您徹底測驗,以防它TheThreeDollarFiftyCentType適用于您的實際用例。
Playground 鏈接到代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/382656.html
