掌握 TypeScript 實用型別工具 Utility Types
在現代 Web 應用程式的開發中,TypeScript 已經成為一個不可或缺的程式語言。在 TypeScript 中,有一組非常強大的工具稱為 Utility Types
,它可以幫助開發者輕鬆地操縱和轉換現有的型別,既可以減少重複定義類似的型別,也可以提高程式碼的可讀性。我在這篇文章中參考了 Hannah Lin 的文章,將 TypeScript 的 Utility Types 也整理為幾個類別,使讀者更容易理解和記住這些工具。
我根據 Utility Types 的功能將其分成以下幾大類:
- 屬性操作類型
- 提取和排除類型
- 函數和實例操作類型
- 字串操作類型
這篇文章將介紹一些常見的 utility types,並展示它們的用法。
屬性操作類型
Partial<T>:將屬性設置為可選
Partial<T> 允許我們將某個類型的所有屬性設定為可選。
interface User {
id: number;
name: string;
age: number;
}
type PartialUser = Partial<User>;
// Infer:
// type PartialUser = {
// id?: number;
// name?: string;
// age?: number;
// }
const updateUser: PartialUser = {
name: 'John'
};
Required<T>:將屬性設置為必需
Required<T> 將某個類型 的所有屬性設定為必需。
interface User {
id?: number;
name?: string;
age?: number;
}
type RequiredUser = Required<User>;
// Infer:
// type RequiredUser = {
// id: number;
// name: string;
// age: number;
// }
const newUser: RequiredUser = {
id: 1,
name: 'Jane',
age: 30
};
Readonly<T>:將屬性設置為唯讀
Readonly<T> 可以將某個類型的所有屬性設定為唯讀,防止這些屬性被修改。
interface User {
id: number;
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
// Infer:
// type ReadonlyUser = {
// readonly id: number;
// readonly name: string;
// readonly age: number;
// }
const readonlyUser: ReadonlyUser = {
id: 1,
name: 'Jane',
age: 30
};
// readonlyUser.id = 2; // Error: Cannot assign to 'id' because it is a read-only property.
Record<K, T>:構建一個物件類型,其屬性鍵是類型 K,屬性值是類型 T。
Record<K, T> 是用來建構一個物件類型,其屬性鍵是類型 K,屬性值是類型 T。
type Page = 'home' | 'about' | 'contact';
interface PageInfo {
title: string;
}
type Pages = Record<Page, PageInfo>;
// Infer:
// type Pages = {
// home: PageInfo;
// about: PageInfo;
// contact: PageInfo;
// }
const pages: Pages = {
home: { title: 'Home' },
about: { title: 'About Us' },
contact: { title: 'Contact' }
};
提取與排除類型
Pick<T, K>:從某個類型中挑選一組屬性來構建新類型
Pick<T, K> 從某個類型中挑選一組屬性來建構新類型。
interface User {
id: number;
name: string;
age: number;
email: string;
}
type UserPreview = Pick<User, 'id' | 'name'>;
// Infer:
// type UserPreview = {
// id: number;
// name: string;
// }
const userPreview: UserPreview = {
id: 1,
name: 'Jane'
};
Omit<T, K>:從某個類型中排除一組屬性來構建新類型
Omit<T, K> 與 Pick<T, K> 相反,從某個類型中排除一組屬性來建構新類型。
interface User {
id: number;
name: string;
age: number;
email: string;
}
type UserWithoutEmail = Omit<User, 'email'>;
// Infer:
// type UserWithoutEmail = {
// id: number;
// name: string;
// age: number;
// }
const userWithoutEmail: UserWithoutEmail = {
id: 1,
name: 'Jane',
age: 30
};
Exclude<T, U>:從某個類型中排除可以分配給另一個類型的所有屬性
Exclude<T, U> 從某個類型中排除可以分配給另一個類型的所有屬性。
type T = 'a' | 'b' | 'c';
type U = 'a';
type ExcludeTU = Exclude<T, U>; // 'b' | 'c'
Extract<T, U>:從某個類型中提取可以分配給另一個類型的所有屬性
Extract<T, U> 則與 Exclude 相反,從某個類型中提取可以分配給另一個類型的所有屬性。
type T = 'a' | 'b' | 'c';
type U = 'a' | 'c';
type ExtractTU = Extract<T, U>; // 'a' | 'c'
NonNullable<T>:排除類型中的 null 和 undefined
NonNullable<T> 用來排除類型中的 null 和 undefined。
type T = string | number | null | undefined;
type NonNullableT = NonNullable<T>; // string | number
函數與實例操作類型
Parameters<T>:獲取函數類型的參數類型組成的元組
Parameters<T> 用來獲取函數類型的參數類型組成的元組。
type FunctionType = (x: number, y: string) => void;
type Params = Parameters<FunctionType>; // [number, string]
ConstructorParameters<T>:獲取構造函數類型的參數類型組成的元組
ConstructorParameters<T> 用來獲取建構函式類型的參數類型組成的元組。
type ClassType = new (x: number, y: string) => void;
type ConstructorParams = ConstructorParameters<ClassType>; // [number, string]
ReturnType<T>:獲取函數類型的返回值類型
ReturnType<T> 用來獲取函數類型的返回值類型。
type FunctionType = () => string;
type ReturnTypeOfFunction = ReturnType<FunctionType>; // string
InstanceType<T>:獲取構造函數類型的實例類型
InstanceType<T> 用來獲取建構函式類型的實例類型。
class User {
constructor(public name: string, public age: number) {}
}
type UserInstance = InstanceType<typeof User>; // User
ThisParameterType<T>:獲取函數類型中的 this 參數類型
ThisParameterType<T> 用來獲取函數類型中的 this 參數類型。
function myFunction(this: { name: string }) {
console.log(this.name);
}
type ThisType = ThisParameterType<typeof myFunction>; // { name: string }
OmitThisParameter<T>:移除函數類型中的 this 參數
OmitThisParameter<T> 用來移除函數類型中的 this 參數。
function myFunction(this: { name: string }) {
console.log(this.name);
}
type NewFunctionType = OmitThisParameter<typeof myFunction>; // () => void
Awaited<T>:解析 Promise 類型,獲取其解析值的類型
Awaited<T> 用來解析 Promise 類型,獲取其解析值的類型。
type ExampleType = Promise<string>;
type AwaitedType = Awaited<ExampleType>; // string
字串操作類型
Uppercase<S>:將字符串類型轉換為大寫
Uppercase<S> 將字串類型轉換為大寫。
type Name = 'john';
type UppercaseName = Uppercase<Name>; // 'JOHN'
Lowercase<S>:將字符串類型轉換為小寫
Lowercase<S> 將字串類型轉換為小寫。
type Name = 'JOHN';
type LowercaseName = Lowercase<Name>; // 'john'
Capitalize<S>:將字符串類型的首字母轉換為大寫
Capitalize<S> 將字串類型的首字母轉換為大寫。
type Name = 'john';
type CapitalizedName = Capitalize<Name>; // 'John'
Uncapitalize<S>:將字符串類型的首字母轉換為小寫
Uncapitalize<S> 將字串類型的首字母轉換為小寫。
type Name = 'John';
type UncapitalizedName = Uncapitalize<Name>; // 'john'