我有一個UNO卡組,我希望它是型別安全的。
卡組陣列中的每張卡都由一個由顏色和值組成的2字符字串表示。我正在使用一個Template Literal Type來表示CardType。
type SpecialCard = "S"/span> | "R"/span> | "D"/span>。// Skip | Reverse | Draw 2
type NumberCard = number;
型別 Color = "R" | "Y" | "G" | "B"。
型別 WildCard = "W"/span> | "W4"/span>;
type CardType = `${Color}${(NumberCard | SpecialCard)}` | WildCard;
現在我想創建一個這樣的卡片集:
const StandardDeck: CardType[] = (["R"/span>, "Y"/span>, "G"/span>, "B"/span>] as Color[] )
.map<CardType[]>((color) =>/span>
[0, 1, 2, 3, 4, 5, 6。7, 8, 9, "S"/span>, "R"/span>, "D"/span>] 。 map<CardType> (
(v) => `${color}${v}`
).flat()
然而,這讓我在這一行出現了錯誤:
(v) => `${color}${v}`
Type '`R${number}` | `Y${number}` | `G${number}` | `B${number}` | `R${string}` | `Y${string}` | `G${string}` /span>不能分配給'CardType'/span>型別。
型別 '`R${string}'不可分配給型別'CardType'。
Type 'string'不可分配給型別'CardType'。
型別 'R${string}'不可分配給型別'"BD"'。
Type 'string'不能分配給型別'"BD"。
uj5u.com熱心網友回復:
type SpecialCard = "S"/span> | "R"/span> | "D"/span>; // Skip | Reverse | Draw 2
type NumberCard = number;
型別 Color = "R" | "Y" | "G" | "B"。
型別 WildCard = "W"/span> | "W4"/span>;
type Indexes = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 !
type CardType = `${Color}${(NumberCard | SpecialCard)}` | WildCard;
const applyColor = <Colors extends Color[]>(color: [...Colors]) =>
<ColorKeys extends Indexes | SpecialCard, ColorMap extends ColorKeys[]>(colorMap: [...ColorMap]) =>
顏色
.map((color) =>
colorMap.map((v): `${Colors[number]}${ColorKeys}` => `${color}${v}`)
).flat()
const makeDeck = applyColor(["R", "Y", "G", "B"] )
// ("r0" | "r4" | "r1" | "r2" | "r3" | "r5" | "r6" | "r7" | "r8" | "r9" | "rr" | "rs" !
// | "RD" | "Y0" | "Y4" | "Y1" | "Y2" | "Y3" | "Y5" | "Y6" | "Y7" | "Y8" | "Y9" | "YR" | "YS" | "YD" | "G0" | ... 24更多 ... | "BD")[]
// 28 24=52個元素在聯盟中
//在運行時值中有完全相同的元素數
const StandardDeck = makeDeck([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "S", "R", "D"] )
解釋
我使用了curry模式來使其更具可讀性,并使用變數元組型別進行推理
正如您可能已經注意到的,為了推斷型別,我使用了一個函式而不僅僅是一個值。
如果您想要輸入復雜的東西,首先要嘗試推斷每個函式引數。推斷得越嚴格越好。
將滑鼠停留在applyColor(["R", "Y", "G", "B"])上。你會看到,陣列被推斷出每個元素,而不僅僅是string[]。與makeDeck相同。
推斷一個元組是很容易的。你只需要為一個元組Colors創建泛型,并應用適當的約束extends Color[]。
在第二個函式中,除了推斷整個元組之外,我還推斷了一個元組元素ColorKeys。我這樣做是因為我在(v) => ${color}${v}``中使用了它來輸入回傳型別。
TypeScript足夠聰明,可以推斷出${color}${v}的確切型別。
如果你對函式引數推理感興趣,你可以閱讀我的文章。這篇文章還沒有完成,但已經有了一些有用的解釋和例子。
P.S.似乎WildCard在運行時不存在。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/332487.html
標籤:
