簡體   English   中英

為什么 Typescript Union + Mapped Types 在有和沒有泛型的情況下工作方式不同

[英]Why does Typescript Union + Mapped Types work differently with and without Generics

我是使用泛型的新手。 下面的代碼有不同的“w0”和“w1”,但代碼看起來是一樣的。

為什么它們不同,以及我如何以相反的方式獲得相反的類型。

我瀏覽了一些文檔,但找不到任何解釋,有沒有文檔可以解釋它們不同類型的原理?

我怎樣才能得到Calc<BaseA> | Calc<BaseB> Calc<BaseA> | Calc<BaseB>沒有CalcGenerics

我怎樣才能得到{ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM