TypeScript高級類型-內置實用工具類型

TypeScript高級類型-內置實用工具類型

預備知識

  1. TypeScript高級類型-Partial
  2. TypeScript高級類型-條件類型(重要前置知識)
  3. TypeScript高級類型-實用技巧

Partial<T>

將泛型 T 中的所有屬性轉化爲可選屬性

/**
 * Make all properties in T optional
 */
type Partial<T> = {
    [P in keyof T]?: T[P];
};

interface IUser {
  name: string;
  age: number;
}

type t = Partial<IUser>;
/* type t = {
	name?: string;
	age?: number
} */

Required<T>

將泛型 T 中的所有屬性轉化爲必選屬性

/**
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};

interface IUser {
  name?: string;
  age?: number;
}

type t = Required<IUser>;
/* type t = {
	name: string;
	age: number
} */

Readonly<T>

將泛型 T 中的所有屬性轉化爲只讀屬性

/**
 * Make all properties in T readonly
 */
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

interface IUser {
  name: string;
  age: number;
}

type t = Readonly<IUser>;
/* type t = {
	readonly name: string;
	readonly age: number
} */

Pick<T, K extends keyof T>

從泛型 T 中檢出指定的屬性並組成一個新的對象類型

/**
 * From T, pick a set of properties whose keys are in the union K
 */
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

interface IUser {
  name: string;
  age: number;
  address: string;
}

type t = Pick<IUser, 'name' | 'age'>;
/* type t = {
	name: string;
	age: number
} */

Record<K extends keyof any, T>

Record 允許從 Union 類型中創建新類型,Union 類型中的值用作新類型的屬性。

經常用於接口 response 類型聲明

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

type Car = 'Audi' | 'BMW' | 'MercedesBenz'
type CarList = Record<Car, {age: number}>

const cars: CarList = {
    Audi: { age: 119 },
    BMW: { age: 113 },
    MercedesBenz: { age: 133 },
}

Exclude<T, U>

從泛型 T 中排除可以賦值給泛型 U 的類型

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

type a = 1 | 2 | 3;

type t = Exclude<a, 1 | 2>;
/* type t = 3 */

Extract<T, U>

從泛型 T 中提取可以賦值給泛型 U 的類型

/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;

type a = 1 | 2 | 3;

type t = Extract<a, 1 | 2>;
/* type t = 1 | 2 */

Omit<T, K extends keyof any>

從泛型 T 中提取出不在泛型 K 中的屬性類型,並組成一個新的對象類型

/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

interface IUser {
  name: string;
  age: number;
  address: string;
}

type t = Omit<IUser, 'name' | 'age'>;
/* type t = {
	address: string;
} */

NonNullable<T>

從泛型 T 中排除掉 nullundefined

/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T extends null | undefined ? never : T;

type t = NonNullable<'name' | undefined | null>;
/* type t = 'name' */

Parameters<T extends (...args: any) => any>

以元組的方式獲得函數的入參類型

/**
 * Obtain the parameters of a function type in a tuple
 */
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

type t = Parameters<(name: string) => any>; // type t = [string]
type t2 = Parameters<((name: string) => any)  | ((age: number) => any)>; // type t2 = [string] | [number]

ConstructorParameters<T extends new (...args: any) => any>

以元組的方式獲得構造函數的入參類型

/**
 * Obtain the parameters of a constructor function type in a tuple
 */
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;

type t = ConstructorParameters<(new (name: string) => any)  | (new (age: number) => any)>;
// type t = [string] | [number]

ReturnType<T extends (...args: any) => any>

獲得函數返回值的類型

/**
 * Obtain the return type of a function type
 */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

type t = ReturnType<(name: string) => string | number>
// type t = string | number

InstanceType<T extends new (...args: any) => any>

獲得構造函數返回值的類型

/**
 * Obtain the return type of a constructor function type
 */
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;

type t = InstanceType<new (name: string) => {name: string, age: number}>
/* 
type h = {
    name: string;
    age: number;
}
*/

總結

  1. 重點理解這些內置的工具類型的定義
  2. 能夠以此爲”引“寫一些工具類型並運用到項目中去
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章