你应该知道的 11 个超棒的 TypeScript 实用类型
选择<类型,键>
省略<类型,键>
只读<类型>
部分<类型>
必填项<类型>
记录<键,类型>
参数<类型>
返回类型<类型>
提取<类型,联合>
排除<类型,排除的联合>
非空类型
结论
本文最初发表于kais.blog。
让我们一起提升你的学习能力! 关注我的推特账号,获取每日开发者技巧。感谢阅读我的文章!
我之前的两篇文章已经向大家介绍了14 个你应该知道的超棒的 JavaScript 数组技巧和10 个你可能不知道的超棒的 JavaScript 字符串技巧。不过,我通常用 TypeScript 写代码。TypeScript 也有很多东西需要学习。所以今天,我想向大家介绍 11 个超棒的 TypeScript 实用类型。有了它们,创建新类型就变得轻而易举了。
您无需进行任何特殊操作。所有实用程序类型默认情况下都是全局可用的。
选择<类型,键>
你可以从给定的类型集合中Pick选择一组。示例展示了一个以 `a`作为第一个参数的函数。参数类型是通过从类型中选择 ` and`属性来构建的。这样,你就不需要在注册新用户时传递 `a` 了。KeysTypesignupuseremailpasswordUserid
interface User {
id: string;
email: string;
password: string;
}
function signup(user: Pick<User, "email" | "password">): User {
//
}
signup({
email: "kai@example.com",
password: "secret",
});
省略<类型,键>
与 `remove` 不同Pick,你可以使用`remove`从你的 `Object` 对象中Omit移除一组属性。示例与前面的类似。在这种情况下,函数的参数包含该类型的所有属性,但缺少 `remove`属性。KeysTypesignupuserUserid
interface User {
id: string;
email: string;
password: string;
}
function signup(user: Omit<User, "id">): User {
//
}
signup({
email: "kai@example.com",
password: "secret",
});
只读<类型>
有时您需要阻止对象的属性被重新赋值。这可以通过Readonly使用工具类型来实现。构造的类型会将所有属性设置为只读。因此,您无法重新赋值该类型的任何属性。在下面的示例中,我们将使用Readonly`and`创建一个新类型。由于该属性现在是只读的,因此User我们无法在此处重新赋值它。password
interface User {
id: string;
email: string;
password: string;
}
const user: Readonly<User> = {
id: "d70989c8-c135-4825-a18c-a62ddf9ae1d5",
email: "kai@example.com",
password: "secret",
};
user.password = "correcthorsebatterystaple";
// ERROR: Cannot assign to 'password' because it is a read-only property.
部分<类型>
您可以使用此方法Partial构造一个类型,其所有属性可以是Type固定的,也可以是可选的。例如,该updateUser函数允许您更新一个对象User。第二个参数期望更新字段。您可以在此处使用Partial该User类型,因此可以fields是该类型中任意字段的组合User。
interface User {
id: string;
email: string;
password: string;
}
function updateUser(user: User, fields: Partial<User>): User {
//
}
const user: User = {
id: "d70989c8-c135-4825-a18c-a62ddf9ae1d5",
email: "kai@example.com",
password: "secret",
};
updateUser(user, { password: "correcthorsebatterystaple" });
必填项<类型>
Required是 `set` 的反义词Partial。你可以用它构造一个所有属性都从Type`set` 变为 `required` 的类型。下面的示例有一个User带有可选avatar属性的类型。但是,我们的变量userWithAvatar要求所有属性都必须存在。因此,会发生错误。
interface User {
id: string;
email: string;
password: string;
avatar?: string;
}
const userWithAvatar: Required<User> = {
id: "d70989c8-c135-4825-a18c-a62ddf9ae1d5",
email: "kai@example.com",
password: "secret",
};
// ERROR: Property 'avatar' is missing in type '{ id: string; email: string; password: string; }' but required in type 'Required<User>'.
记录<键,类型>
使用`utility type`,您可以轻松地构造一个以`A` 为键、 `B` 为值的Record新类型。在本例中,每个 `A`都有一个角色。我们想要描述一个对象,该对象根据各自的角色对`A`和`B` 进行分组。使用 `utility type` ,我们可以告诉 TypeScript 编译器,该对象以 ` A` 为键,以 `B` 数组为值。此外,为了更明确地表达,我们也可以使用 `A`而不是 ` B` 来表示键。KeysTypeUseruserAuserBRecordstringUserUser["role"]string
interface User {
id: string;
email: string;
password: string;
role: string;
}
const userA: User = {
id: "d70989c8-c135-4825-a18c-a62ddf9ae1d5",
email: "kai@example.com",
password: "secret",
role: "administrator",
};
const userB: User = {
id: "c0e26c7e-9787-4d56-81b4-4440759e251c",
email: "katharina@example.com",
password: "correcthorsebatterystaple",
role: "moderator",
};
const usersGroupedByRole: Record<string, User[]> = {
administrator: [userA],
moderator: [userB],
};
参数<类型>
用于Parameters提取函数的参数。这将创建一个包含这些参数的元组类型。假设你想初始化一个保存signup函数参数的变量。借助此方法,Parameters你可以提取函数的参数并创建一个元组类型。然后,你可以在需要的时候signup使用它。parameters
interface User {
id: string;
email: string;
password: string;
}
function signup(email: string, password: string): User {
//
}
type SignupParameters = Parameters<typeof signup>;
// = [email: string, password: string]
const parameters: SignupParameters = ["kai@example.com", "secret"];
signup(...parameters);
返回类型<类型>
实用类型ReturnType通过提取函数的返回类型来提供帮助。请看下面的例子。我们希望ValidationResult通过查看函数的返回类型来构建类型validate。这里很简单,你也可以boolean直接使用。但是,有时能够提取函数的返回类型会很方便。
interface User {
id: string;
email: string;
password: string;
}
function validate(user: User): boolean {
//
}
type ValidationResult = ReturnType<typeof validate>;
// = boolean
提取<类型,联合>
有时,您需要从类型联合体中提取特定类型。为此,您可以使用实用类型。该类型会保留联合体中所有可赋值给 `T` 的Extract成员。在以下示例中,我们将使用字符串联合体。我们将从中提取一部分作为 `T`和`C` 类型。对于`T`,我们将提取所有可赋值给 `C` 的联合成员。TypeUnionTypeATypeBTypeCFunction
type TypeA = Extract<"apple" | "banana" | "cherry", "apple">;
// = "apple"
type TypeB = Extract<"apple" | "banana" | "cherry", "apple" | "banana">;
// = "apple" | "banana"
type TypeC = Extract<string | (() => string), Function>;
// = () => string
排除<类型,排除的联合>
实用Exclude类型与实用类型相反Extract。这次,它会移除所有Type可赋值的联合体成员ExcludedUnion。与之前的示例类似,这里我们也使用了字符串联合体。但与上次不同的是,这次我们要移除联合体成员,而不是保留它们。
type TypeA = Exclude<"apple" | "banana" | "cherry", "apple">;
// = "banana" | "cherry"
type TypeB = Exclude<"apple" | "banana" | "cherry", "apple" | "banana">;
// = "cherry"
type TypeC = Exclude<string | (() => string), Function>;
// = string
非空类型
NonNullable其工作方式与实用程序类型类似Exclude。它会从给定的集合中排除 ` nullA` 和`B`。与前两个示例类似,我们通过从给定的集合中移除联合成员来构造新类型 `A`和`B` 。这里,` A` 和/或 `B`会被移除。undefinedTypeTypeATypeBTypenullundefined
type TypeA = NonNullable<"apple" | null>;
// = "apple"
type TypeB = NonNullable<"apple" | null | undefined>;
// = "apple"
结论
以上是对一些最常用实用类型的简要概述。它们用途广泛,几乎每个项目我都会用到。当然,实用类型远不止这些。请查阅官方文档了解更多信息!此外,你还可以找到更多类似的类型。例如,该type-fest软件包会为你的项目添加许多必要的类型。
非常感谢您阅读这篇文章。请考虑将其分享给您的朋友和同事。下次见!
让我们一起提升你的学习能力! 关注我的推特账号,获取每日开发者技巧。感谢阅读我的文章!
本文最初发表于kais.blog。
文章来源:https://dev.to/kais_blog/11-awesome-typescript-utility-types-you-should-know-4a8j