![](/img/trans.png)
[英]Typescript: Narrowing down mapped types does not work with generics
[英]Why does Typescript Union + Mapped Types work differently with and without Generics
我是使用泛型的新手。 下面的代碼有不同的“w0”和“w1”,但代碼看起來是一樣的。
為什么它們不同,以及我如何以相反的方式獲得相反的類型。
我瀏覽了一些文檔,但找不到任何解釋,有沒有文檔可以解釋它們不同類型的原理?
我怎樣才能得到Calc<BaseA> | Calc<BaseB>
Calc<BaseA> | Calc<BaseB>
沒有Calc
和Generics
。
我怎樣才能得到{ type: "A" | "B"; flag: number; }
{ type: "A" | "B"; flag: number; }
{ type: "A" | "B"; flag: number; }
與Generics
。
type BaseA = {
type: 'A'
name: string
flag: number
}
type BaseB = {
type: 'B'
id: number
flag: number
}
type Base = BaseA | BaseB
type w0 = {
[k in keyof Base]: Base[k]
}
/*
w0 = {
type: "A" | "B";
flag: number;
}
*/
type Calc<W> = {
[k in keyof W]: W[k]
}
type w1 = Calc<Base>
/*
w1 = Calc<BaseA> | Calc<BaseB>
*/
type z0 = Exclude<w0,BaseA>
// z0 = w0
type z1 = Exclude<w1,BaseA>
// z1 = BaseB
第一個問題很容易解決:
type Q1 = {
[B in Base as B["type"]]: {
[K2 in keyof B]: B[K2]
}
}[Base["type"]]
// type Q1 = {
// type: 'A';
// name: string;
// flag: number;
// } | {
// type: 'B';
// id: number;
// flag: number;
// }
我們首先映射Base
中的每個元素,並將type
鍵作為結果類型的鍵。 對於每個元素,我們可以映射元素的鍵。 最后,我們用Base["type"]
索引這個類型來獲得聯合。
您現在可以用Calc
替換內部映射。
type Q1 = {
[B in Base as B["type"]]: Calc<B>
}[Base["type"]]
// type Q1 = Calc<BaseA> | Calc<BaseB>
第二個問題有點棘手。 它是由分布式條件類型引起的。 我發現只能用這個技巧來禁用分配性:
type Calc2<W extends [any]> = {
[k in keyof W[0]]: W[0][k]
}
type Q2 = Calc2<[Base]>
// type Q2 = {
// type: "A" | "B";
// flag: number;
// }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.