Typescript高级类型汇总
本文旨在沉淀常用的TS高级类型
示例
举个例子,你有两种Response类型:
UserProfileResponse
interface UserProfileResponse {
id: number;
name: string;
email: string;
phone: string;
avatar: string;
}
LoginResponse
interface LoginResponse {
id: number;
name: string;
}
我们可以为 UserProfileResponse 定义类型,并为 LoginResponse 选择一些属性,而不是重复定义属性。
type LoginResponse = Pick<UserProfileResponse, "id" | "name">;
以下是一些工具函数,可以帮助你写出更加高效、简洁的代码。
Uppercase
将类型所有属性大写
type Role = "admin" | "user" | "guest";
// Bad practice 💩
type UppercaseRole = "ADMIN" | "USER" | "GUEST";
// Good practice ✅
type UppercaseRole = Uppercase<Role>; // "ADMIN" | "USER" | "GUEST"
Lowercase
将类型所有属性小写
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice 💩
type LowercaseRole = "admin" | "user" | "guest";
// Good practice ✅
type LowercaseRole = Lowercase<Role>; // "admin" | "user" | "guest"interface LoginResponse {
id: number;
name: string;
}
Capitalize
将类型所有属性首字母大写
type Role = "admin" | "user" | "guest";
// Bad practice 💩
type CapitalizeRole = "Admin" | "User" | "Guest";
// Good practice ✅
type CapitalizeRole = Capitalize<Role>; // "Admin" | "User" | "Guest"
Uncapitalize
将类型所有属性首字母大写取消
type Role = "Admin" | "User" | "Guest";
// Bad practice 💩
type UncapitalizeRole = "admin" | "user" | "guest";
// Good practice ✅
type UncapitalizeRole = Uncapitalize<Role>; // "admin" | "user" | "guest"
Partial
type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
将类型所有属性变为可选
interface User {
name: string;
age: number;
password: string;
}
// Bad practice 💩
interface PartialUser {
name?: string;
age?: number;
password?: string;
}
// Good practice ✅
type PartialUser = Partial<User>;
Required
type Required<T> = { [P in keyof T]-?: T[P]; }
将类型所有属性改成不可选,与Partial相反
interface User {
name?: string;
age?: number;
password?: string;
}
// Bad practice 💩
interface RequiredUser {
name: string;
age: number;
password: string;
}
// Good practice ✅
type RequiredUser = Required<User>;
Readonly
type Readonly<T> = { readonly [P in keyof T]: T[P]; }
将类型所有属性变成只读
interface User {
role: string;
}
// Bad practice 💩
const user: User = { role: "ADMIN" };
user.role = "USER";
// Good practice ✅
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = { role: "ADMIN" };
user.role = "USER"; // Error: Cannot assign to 'role' because it is a read-only property.
Record
type Record<K extends string | number | symbol, T> = { [P in K]: T; }
构建一个具有类型T的一组属性K的类型。每个属性K都被映射到类型T上。
interface Address {
street: string;
pin: number;
}
interface Addresses {
home: Address;
office: Address;
}
// Alternative ✅
type AddressesRecord = Record<"home" | "office", Address>;
Pick
type Pick<T, K extends keyof T> = { [P in K]: T[P]; }
在旧类型中选出一些属性,组成新类型
interface User {
name: string;
age: number;
password: string;
}
// Bad practice 💩
interface UserPartial {
name: string;
age: number;
}
// Good practice ✅
type UserPartial = Pick<User, "name" | "age">;
Omit
type Omit<T, K extends string | number | symbol> = { [P in Exclude<keyof T, K>]: T[P]; }
在旧类型中剔除一些属性,变成新类型
interface User {
name: string;
age: number;
password: string;
}
// Bad practice 💩
interface UserPartial {
name: string;
age: number;
}
// Good practice ✅
type UserPartial = Omit<User, "password">;
Exclude
type Exclude<T, U> = T extends U ? never : T
构造一个具有 Type 的所有属性的类型,除了键在联合类型 Excluded 中的那些。
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice 💩
type NonAdminRole = "USER" | "GUEST";
// Good practice ✅
type NonAdmin = Exclude<Role, "ADMIN">; // "USER" | "GUEST"
Extract
type Extract<T, U> = T extends U ? T : never
构造一个具有 Type 的所有属性的类型,其键在联合类型 Extract 中。
type Role = "ADMIN" | "USER" | "GUEST";
// Bad practice 💩
type AdminRole = "ADMIN";
// Good practice ✅
type Admin = Extract<Role, "ADMIN">; // "ADMIN"
NonNullable
type NonNullable<T> = T extends null | undefined ? never : T
剔除空属性,变成新类型
type Role = "ADMIN" | "USER" | null;
// Bad practice 💩
type NonNullableRole = "ADMIN" | "USER";
// Good practice ✅
type NonNullableRole = NonNullable<Role>; // "ADMIN" | "USER"