[course] Making TypeScript Stick
keywords: typescript
, frontendmasters
本篇非原創文章,內容整理自 Making TypeScript Stick @ Frontend Masters
Recent updates to TypeScript
Variadic Tuple Types
在 TypeScript 4 之前,雖然可以用 [number, ...T[]]
這種寫法:
// https://www.typescript-training.com/course/making-typescript-stick/03-recent-updates-to-typescript/
enum Sandwich {
Hamburger,
VeggieBurger,
GrilledCheese,
BLT,
}
// tuple
type SandwichOrder = [number, Sandwich, ...string[]];
const order1: SandwichOrder = [12.99, Sandwich.Hamburger, 'lettuce'];
// highlight-tart
// 在 TypeScript 4 之前,可以使用 ...T[] 這樣的寫法來讓 TS 推斷出 T 的型別,但是
function tail<T>(args: readonly [number, ...T[]]) {
const [_ignored, ...rest] = args;
return rest;
}
// 推斷出的結果是 (string | Sandwich)[],失去了原本 tuple 的型別資訊,應該要是 [Sandwich, ...string[]] 才對
const orderWithoutTotal = tail(order1);
// highlight-tart
但這種寫法會使得 TypeScript 無法正確反映出 Tuple 的型別。
在 TypeScript 4 之後,我們可以用 [number, ...T]
下面這種寫法,讓它正確推斷出 tuple 的型別:
// 在 TypeScript 4 之後,可以使用 ...T 這樣的寫法來讓 TS 正確推斷出 tuple
function tail<T extends any[]>(args: readonly [number, ...T]) {
const [_ignored, ...rest] = args;
return rest;
}
// 如此,能正確推斷出 [Sandwich, ...string[]] 的 tuple
const orderWithoutTotal = tail(order1);
如此,就能夠正確推斷出 tuple 型別的內容。
更進一步來說,就是 TypeScript 的 tuple 也支援 spread operator 的使用:
// Arr 會是 [number, string, boolean, boolean]
type Arr = [...[number, string], ...[boolean, boolean]];
const arr: Arr = [1, 'str', true, false];