TypeScript中的工具类型

TypeScript中的工具类型

本文介绍了TypeScript中的工具类型。

YouTube Video

TypeScript中的工具类型

TypeScript中的工具类型是基于现有类型创建新类型的便捷工具。这使得类型定义更加灵活,并提高了代码的可重用性。在这里,我们将详细解释常用的工具类型,并通过示例代码讨论如何使用每种工具类型。

Partial<T>

Partial<T>使对象类型的所有属性变为可选(允许undefined)。当你只需要使用原类型中的某些属性时,这将非常有用。

 1interface User {
 2  id: number;
 3  name: string;
 4  age: number;
 5}
 6
 7function updateUser(user: Partial<User>) {
 8  console.log(user);
 9}
10
11updateUser({ name: "Alice" }); // Updates only 'name'
  • 在上述示例中,使用Partial<User>使User类型的所有属性变为可选。因此,在updateUser函数中,你可以只传递属性的一个子集。

Required<T>

Required<T>将所有属性(包括可选属性)变为必填。当你想将可选属性转换为必填属性时,可以使用它。

 1interface User {
 2  id: number;
 3  name?: string;
 4  age?: number;
 5}
 6
 7function createUser(user: Required<User>) {
 8  console.log(user);
 9}
10
11// createUser({ id: 1 }); // Error: 'name' and 'age' are required
12createUser({ id: 1, name: "Alice", age: 25 });
  • 通过使用Required<User>,像nameage这样的属性被视为必填。

Readonly<T>

Readonly<T>使对象的所有属性变为只读。这可以防止对象的值被更改。

 1interface User {
 2  id: number;
 3  name: string;
 4}
 5
 6const user: Readonly<User> = {
 7  id: 1,
 8  name: "Alice"
 9};
10
11// user.id = 2; // Error: 'id' is read-only
12console.log(user);
  • 通过使用Readonly<T>,可以保护对象的属性不被更改。当你想在开发过程中防止数据被意外修改时,这非常有效。

Record<K, T>

Record<K, T>创建具有指定键和值类型的映射类型。K是键的类型(例如stringnumber),T是值的类型。

 1type Roles = "admin" | "user" | "guest";
 2interface ReadWritePermissions {
 3  read: boolean;
 4  write: boolean;
 5}
 6
 7const rolePermissions: Record<Roles, ReadWritePermissions> = {
 8  admin: { read: true, write: true },
 9  user: { read: true, write: false },
10  guest: { read: false, write: false },
11};
12
13console.log(rolePermissions);
  • 当你想定义键值对时,Record<K, T>非常有用。在上述示例中,基于用户角色定义了权限。

Pick<T, K>

Pick<T, K>从对象类型中仅提取指定的属性。你可以通过仅提取必要的属性来创建一个新类型。

 1interface User {
 2  id: number;
 3  name: string;
 4  age: number;
 5}
 6
 7type UserSummary = Pick<User, "id" | "name">;
 8
 9const summary: UserSummary = {
10  id: 1,
11  name: "Alice"
12};
13
14console.log(summary);
  • 通过使用Pick<T, K>,可以从对象类型中提取特定属性并将其作为新类型。例如,在上述示例中,只提取了idname

Omit<T, K>

Omit<T, K>从对象类型中排除指定的属性。这是Pick的反向操作。

 1interface User {
 2  id: number;
 3  name: string;
 4  age: number;
 5  email: string;
 6}
 7
 8type UserWithoutEmail = Omit<User, "email">;
 9
10const userWithoutEmail: UserWithoutEmail = {
11  id: 1,
12  name: "Alice",
13  age: 25
14};
15
16console.log(userWithoutEmail);
  • 通过使用Omit<T, K>,您可以通过排除指定的属性创建一个新类型。在上面的例子中,email属性被排除。

Exclude<T, U>

Exclude<T, U>通过从联合类型T中移除类型U来创建一个新类型。当您想要移除特定类型时使用。

1type Status = "active" | "inactive" | "pending";
2type ExcludedStatus = Exclude<Status, "pending">;
3
4const userStatus: ExcludedStatus = "active"; // "pending" is excluded, so it cannot be chosen
5console.log(userStatus);
  • 通过使用Exclude<T, U>,您可以移除联合类型中不需要的类型。在上面的例子中,由于"pending"被排除,只能选择"active""inactive"

Extract<T, U>

Extract<T, U>提取联合类型T中与类型U匹配的部分。当您只想提取特定类型时非常有用。

1type Status = "active" | "inactive" | "pending";
2type ActiveStatus = Extract<Status, "active" | "pending">;
3
4const userStatus: ActiveStatus = "active"; // "inactive" cannot be chosen
5console.log(userStatus);
  • Extract<T, U>执行的是Exclude的反向操作。在上面的例子中,仅可以选择"active""pending"

NonNullable<T>

NonNullable<T>创建一个排除nullundefined的类型。当您想从可选类型中排除这些值时非常有帮助。

1type UserName = string | null | undefined;
2type ValidUserName = NonNullable<UserName>;
3
4const userName: ValidUserName = "Alice"; // null and undefined cannot be chosen
5console.log(userName);
  • NonNullable<T> 排除了 nullundefined,确保值是存在的。

结论

TypeScript的工具类型是使类型定义更加简洁和灵活的强大工具。理解并妥善使用PartialRequiredReadonlyRecord等基本工具类型,可以提高代码的可重用性和可维护性。掌握这些类型可以支持更强大且安全的类型定义,从而实现高效开发。

TypeScript的keyof操作符

TypeScript的keyof操作符用于获取对象类型的所有属性名。使用此操作符,您可以将对象类型的键获取为联合类型。这对于编写类型安全的代码非常有用。

基本用法

1interface Person {
2    name: string;
3    age: number;
4    email: string;
5}
6
7// Use keyof to get the property names of Person
8type PersonKeys = keyof Person; // "name" | "age" | "email"

示例用法

在函数参数中使用它

您可以使用 keyof 定义一个函数,该函数的类型基于对象的特定属性。

 1function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
 2    return obj[key];
 3}
 4
 5const person: Person = { name: "Alice", age: 30, email: "alice@example.com" };
 6const userName = getProperty(person, "name"); // type is string
 7const age = getProperty(person, "age");   // type is number
 8
 9console.log("Name:", userName);
10console.log("Age:", age);
  • 此函数根据指定的键,采用类型安全的方式从对象中获取属性。

增强类型约束

通过使用 keyof,您可以确保传递给函数的键在编译时被验证。

1// Passing an invalid property name results in an error
2const invalid = getProperty(person, "invalidKey"); // Error
  • 此代码演示了指定不存在的属性名会导致编译时错误。

总结

  • keyof 操作符用于获取对象类型的所有属性名称。
  • 您可以将属性名称作为联合类型获取,从而实现类型安全的代码。
  • 通过在函数参数中使用它,您可以限制函数仅接受有效的属性名称。

通过这种方式,keyof 操作符增强了 TypeScript 中的类型安全性,并帮助您编写更健壮的代码。

您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。

YouTube Video