Utility Types 介紹
常用的 Utility Types 和實作介紹。
Union Type 相關
Exclude
移除某個 Union Type 的值
type Exclude<T, U> = T extends U ? never : T;
type AllRoles = "admin" | "editor" | "viewer";
type ForbiddenRoles = "editor" | "viewer";
type AllowedRoles = Exclude<UserRoles, ForbiddenRoles>;
// "admin"
Extract
取出某個Union Type
的值
type Extract<T, U> = T extends U ? T : never;
type AllRoles = "admin" | "editor" | "viewer";
type ActiveRoles = "admin" | "viewer";
type ActiveUserRoles = Extract<AllRoles, ActiveRoles>;
// "admin" | "viewer"
Object 相關
Record
可以透過給 property 和 type 的方式創造 object
type Record<K extends keyof any, T> = {
[P in K]: T;
};
type UserPermissions = Record<"read" | "write" | "delete", boolean>;
Omit
可以移除 object 中某幾個 property 和 type
type Omit<T, K extends keyof any> = { [P in Exclude<keyof T, K>]: T[P] };
Pick
可以只取 object 中某幾個 property 和 type
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Partial
把整個 object 的屬性改成可選的
type Partial<T> = { [P in keyof T]?: T[P] | undefined };
範例:
type UserProfile = {
name: string;
age: number;
email: string;
};
type PublicUserProfile = Omit<UserProfile, "email">;
// { name: string; age: number; }
type ContactInfo = Pick<UserProfile, "email">;
// { email: string; }
type UpdateUserProfile = Partial<UserProfile>;
// { name?: string; age?: number; email?: string; }
Function 相關
- ReturnType<T>
type ReturnType<T extends (...args: any) => any> = T extends (
...args: any
) => infer R
? R
: any;
- Parameters<T>
type Parameters<T extends (...args: any) => any> = T extends (
...args: infer P
) => any
? P
: never;
範例:
function getUserInfo(userId: number): { name: string; age: number } {
return {
name: "John",
age: 30,
};
}
type UserInfo = ReturnType<typeof getUserInfo>;
// { name: string; age: number; }
type GetUserParams = Parameters<typeof getUserInfo>;
// [userId: number]
建立自己的 Utility Types
透過各種組合,也可以建立出自己的 Utility Types。 以下是一個範例,PickByValue 用來選擇型別中屬性值為指定型別的屬性:
type PickByValue<T, V> = Pick<
T,
{ [K in keyof T]: T[K] extends V ? K : never }[keyof T]
>;
type User = {
name: string;
age: number;
};
type StringProperties = PickByValue<User, string>; // { name: string; }