TypeScript - Utility Types

你好,未來的編程巫師們!今天,我們將踏上一段令人興奮的旅程,探索 TypeScript 的神奇領域:Utility Types。別擔心如果你是編程新手;我將成為你的友好導遊,我們將一起逐步探索這些概念。所以,拿起你的虛擬魔杖(鍵盤),讓我們一起深入探訪!

TypeScript - Utility Types

Utility Types 是什麼?

在我們開始之前,讓我們先了解什麼是 Utility Types。想像一下你有一個裝滿各種工具的工具箱。每個工具都能幫助你更有效率地完成特定任務。這正是 TypeScript 中的 Utility Types —— 它們是預先建造的工具,幫助我們輕鬆地操作和轉換類型。

現在,讓我們一一看看這些神奇的工具!

TypeScript 中的 Partial Type

Partial 類型就像一個魔法,它使物件中的所有屬性變為可選。當你想創建一個不需要指定所有屬性的物件時,它非常有用。

讓我們看看它是如何運作的:

interface Wizard {
name: string;
age: number;
house: string;
}

function updateWizard(wizard: Wizard, fieldsToUpdate: Partial<Wizard>) {
return { ...wizard, ...fieldsToUpdate };
}

const harryPotter: Wizard = {
name: "Harry Potter",
age: 11,
house: "Gryffindor"
};

const updatedHarry = updateWizard(harryPotter, { age: 17 });
console.log(updatedHarry);
// 輸出: { name: "Harry Potter", age: 17, house: "Gryffindor" }

在這個例子中,Partial<Wizard> 讓我們能夠只更新 Harry 的年齡,而不需要指定其他所有屬性。這就像揮動魔杖並說,“部分顯現魔法!”

TypeScript 中的 Required Type

Required 類型是 Partial 的相反。它就像施展一個魔法,使物件中的所有屬性都變為必填,即使它們原本是可選的。

interface MagicalCreature {
name: string;
power?: string;
age?: number;
}

const dragon: Required<MagicalCreature> = {
name: "Norwegian Ridgeback",
power: "Fire Breath",
age: 2
};

// 這會導致錯誤:
// const unicorn: Required<MagicalCreature> = {
//   name: "Silver Horn"
// };

在這裡,即使原始接口中的 powerage 是可選的,Required 類型也使它們變為必填。這就像說,“召喚所有屬性!”

TypeScript 中的 Pick Type

Pick 類型允許你從現有的類型中選擇特定的屬性來創建一個新的類型。這就像使用召喚咒語來呼唤你需要的屬性。

interface Potion {
name: string;
ingredients: string[];
brewingTime: number;
effect: string;
}

type PotionLabel = Pick<Potion, 'name' | 'effect'>;

const polyjuicePotion: PotionLabel = {
name: "Polyjuice Potion",
effect: "Transforms the drinker into another person"
};

在這個例子中,我們創建了一個新的類型 PotionLabel,它只包括 Potion 接口中的 nameeffect 屬性。這對於当你只需要幾個特定細節時非常完美!

TypeScript 中的 Omit Type

Omit 類型是 Pick 的相反。它通過從現有的類型中刪除特定的屬性來創建一個新的類型。這就像對某些屬性施展消失咒!

interface SpellBook {
title: string;
author: string;
pages: number;
secretSpell: string;
}

type PublicSpellBook = Omit<SpellBook, 'secretSpell'>;

const beginnerSpellBook: PublicSpellBook = {
title: "Standard Book of Spells, Grade 1",
author: "Miranda Goshawk",
pages: 250
};

在這裡,我們創建了一個 PublicSpellBook 類型,它包括 SpellBook 的所有屬性,除了 secretSpell。這就像說,“除了秘密,顯示一切!”

TypeScript 中的 Readonly Type

Readonly 類型就像對你的屬性施加一個保護咒語。它使類型中的所有屬性變為唯讀,防止意外修改。

interface Wand {
wood: string;
core: string;
length: number;
}

const harryWand: Readonly<Wand> = {
wood: "Holly",
core: "Phoenix feather",
length: 11
};

// 這會導致錯誤:
// harryWand.length = 12;

使用 Readonly,我們確保一旦創建了魔杖,其屬性就不能被更改。這就像在對象上施加一個不可摧壞的咒語!

TypeScript 中的 ReturnType Type

ReturnType 效用類型允許我們提取函數的返回類型。這就像使用顯形術來窺視函數並看它返回什麼!

function castSpell(spellName: string): { name: string, power: number } {
// 施法邏輯在這裡
return { name: spellName, power: Math.random() * 100 };
}

type SpellResult = ReturnType<typeof castSpell>;

const lumos: SpellResult = {
name: "Lumos",
power: 50
};

在這個例子中,SpellResult 被推导為 { name: string, power: number },這是 castSpell 的返回類型。這在處理複雜函數時非常有用!

TypeScript 中的 Record Type

Record 類型是一個強大的魔法,它創建一個具有特定鍵類型和值類型的物件類型。這就像召喚一個神奇的地圖,你定義鍵和值應該是什麼。

type HouseCup = Record<string, number>;

const housePoints: HouseCup = {
"Gryffindor": 472,
"Hufflepuff": 352,
"Ravenclaw": 426,
"Slytherin": 472
};

在這裡,HouseCup 是一個類型,其鍵是字符串(學院名稱),值是數字(積分)。它確保我們的學院積分物件具有正確的結構。

TypeScript 中的 NonNullable Type

NonNullable 類型就像施展一個魔法來驅逐 null 和 undefined 值。它通過從給定的類型中排除 null 和 undefined 來創建一個新的類型。

type MagicalItem = string | number | null | undefined;

type DefiniteMagicalItem = NonNullable<MagicalItem>;

const definiteItem: DefiniteMagicalItem = "Invisibility Cloak";
// 這會導致錯誤:
// const nullItem: DefiniteMagicalItem = null;

在這個例子中,DefiniteMagicalItem 是一個類型,可以是字符串或數字,但不能是 null 或 undefined。這在你想確保你正在使用實際值時非常完美!

Utility Types 速查表

這裡是我們討論過的所有 Utility Types 的快速參考表:

效用類型 描述 示例
Partial 使 T 中的所有屬性可選 Partial<Wizard>
Required 使 T 中的所有屬性必填 Required<MagicalCreature>
Pick<T, K> 從 T 中創建一個只包含 K 屬性的類型 Pick<Potion, 'name' | 'effect'>
Omit<T, K> 從 T 中創建一個不包含 K 屬性的類型 Omit<SpellBook, 'secretSpell'>
Readonly 使 T 中的所有屬性唯讀 Readonly<Wand>
ReturnType 提取函數類型 T 的返回類型 ReturnType<typeof castSpell>
Record<K, T> 創建一個具有鍵類型 K 和值類型 T 的物件類型 Record<string, number>
NonNullable 通過從 T 中排除 null 和 undefined 來創建一個新的類型 NonNullable<MagicalItem>

年輕的巫師們,你現在已經掌握了 TypeScript Utility Types 的基本咒語。記住,就像任何魔法一樣,這些類型在練習中會變得更加強大。所以,繼續實驗,很快你就能像說“Wingardium Leviosa”一樣輕鬆施展這些類型!

Credits: Image by storyset