作者:Rahul Sharma
译者:前端小智
来源:dev
在类型检查方面,Typescript非常强大,但有时当一些类型是其他类型的子集,而你需要为它们定义类型检查时,它就变得很乏味。
举个例子,你有2个响应类型。
interface UserProfileResponse {
id: number;
name: string;
email: string;
phone: string;
avatar: string;
}
interface LoginResponse {
id: number;
name: string;
}
我们可以为 UserProfileResponse 定义类型,并为 LoginResponse 挑选一些属性,而不是定义相同上下文的 LoginResponse 和 UserProfileResponse 的类型。
type LoginResponse = Pick;
让我们来了解一些可以帮助你写出更好的代码的实用函数。
Uppercase
构建一个类型的所有属性都设置为大写的类型。
type Role = "admin" | "user" | "guest";
// Bad practice
type UppercaseRole = "ADMIN" | "USER" | "GUEST";
// Good practice ✅
type UppercaseRole = Uppercase; // "ADMIN" | "USER" | "GUEST"
Lowercase
构建一个类型的所有属性都设置为小写的类型。与 Uppercase 相反。
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice
type LowercaseRole = "admin" | "user" | "guest";
// Good practice ✅
type LowercaseRole = Lowercase; // "admin" | "user" | "guest"
Capitalize
构建一个类型的所有属性都设置为大写开头的类型。
type Role = "admin" | "user" | "guest";
// Bad practice
type CapitalizeRole = "Admin" | "User" | "Guest";
// Good practice ✅
type CapitalizeRole = Capitalize; // "Admin" | "User" | "Guest"
Uncapitalize
构建一个类型的所有属性都设置为非大写的类型。与Capitalize相反。
type Role = "Admin" | "User" | "Guest";
// Bad practice
type UncapitalizeRole = "admin" | "user" | "guest";
// Good practice ✅
type UncapitalizeRole = Uncapitalize; // "admin" | "user" | "guest"
Partial
构建一个类型的所有属性都设置为可选的类型。
interface User {
name: string;
age: number;
password: string;
}
// Bad practice
interface PartialUser {
name?: string;
age?: number;
password?: string;
}
// Good practice ✅
type PartialUser = Partial;
Required
构建一个由Type的所有属性组成的类型,设置为必填。与Partial相反。
interface User {
name?: string;
age?: number;
password?: string;
}
// Bad practice
interface RequiredUser {
name: string;
age: number;
password: string;
}
// Good practice ✅
type RequiredUser = Required;
Readonly
构建一个由Type的所有属性组成的类型,设置为只读。
interface User {
role: string;
}
// Bad practice
const user: User = { role: "ADMIN" };
user.role = "USER";
// Good practice ✅
type ReadonlyUser = Readonly;
const user: ReadonlyUser = { role: "ADMIN" };
user.role = "USER"; // Error: Cannot assign to 'role' because it is a read-only property.
Record
Record是一个很好用的工具类型。他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型,
interface Address {
street: string;
pin: number;
}
interface Addresses {
home: Address;
office: Address;
}
// 或者
type AddressesRecord = Record<"home" | "office", Address>;
Pick
从一个复合类型中,取出几个想要的类型的组合
interface User {
name: string;
age: number;
password: string;
}
// Bad practice
interface UserPartial {
name: string;
age: number;
}
// Good practice ✅
type UserPartial = Pick;
Omit
以一个类型为基础支持剔除某些属性,然后返回一个新类型。
interface User {
name: string;
age: number;
password: string;
}
// Bad practice
interface UserPartial {
name: string;
age: number;
}
// Good practice ✅
type UserPartial = Omit;
Exclude
Exclude
,该工具类型能够从类型T中剔除所有可以赋值给类型U的类型。
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice
type NonAdminRole = "USER" | "GUEST";
// Good practice ✅
type NonAdmin = Exclude; // "USER" | "GUEST"
Extract
Extract 的功能,与 Exclude 相反,它是 提取 T 中可以赋值给 U 的类型。
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice
type AdminRole = "ADMIN";
// Good practice ✅
type Admin = Extract; // "ADMIN"
NonNullable
构建一个类型的所有属性都设置为非空的类型。
type Role = "ADMIN" | "USER" | null;
// Bad practice
type NonNullableRole = "ADMIN" | "USER";
// Good practice ✅
type NonNullableRole = NonNullable; // "ADMIN" | "USER"
编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dev.to/devsmitra/13-t...
交流
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。