TypeScript - 实用类型

你好,未来的编程法师们!今天,我们将踏上一段激动人心的旅程,探索 TypeScript 实用类型的魔法世界。如果你是编程新手,不用担心;我将作为你友好的向导,我们会一起逐步探索这些概念。所以,拿起你的虚拟魔杖(键盘),让我们一起深入吧!

TypeScript - Utility Types

什么是实用类型?

在我们开始之前,让我们先了解一下实用类型是什么。想象你有一个装满各种工具的工具箱。每个工具都能帮助你更高效地完成特定任务。这正是 TypeScript 中的实用类型的作用——它们是预制的工具,帮助我们轻松地操作和转换类型。

现在,让我们逐一看看这些神奇的工具!

TypeScript 中的 Partial 类型

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 类型

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 类型

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 类型

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 类型

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 类型

ReturnType 实用类型允许我们提取函数的返回类型。这就像使用 Legilimency 去窥探一个函数并看到它返回什么!

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 类型

Record 类型是一种强大的魔法,它创建了一个具有特定键类型和值类型的对象类型。这就像召唤一个神奇的地图,你可以定义键和值应该是什么。

type HouseCup = Record<string, number>;

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

在这里,HouseCup 是一个类型,其键是字符串(学院名称),值是数字(分数)。它确保我们的学院分数对象具有正确的结构。

TypeScript 中的 NonNullable 类型

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。当你想要确保你正在处理实际值时,这非常完美!

实用类型速查表

以下是我们在本文中讨论的所有实用类型的快速参考表:

实用类型 描述 示例
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 实用类型的基础咒语。记住,就像任何魔法一样,这些类型在实践中会变得更强大。所以,继续实验,很快你就能像说“Wingardium Leviosa”一样轻松地使用这些类型了!

Credits: Image by storyset