typescript內建工具泛型(總結)
阿新 • • 發佈:2021-06-23
1、Partial
原始碼實現:
type Partial<T> = { [P in keyof T]?: T[P]; };
作用:它用來將 T 中的所有的屬性都變成可選的。
案例:
type Animal = { name: string, category: string, age: number, eat: () => number } type PartOfAnimal = Partial<Animal>; const ww: PartOfAnimal = { eat: () => {return 233 } }; // 屬性全部可選後,可以只賦值部分屬性了
2、Record
原始碼實現:
type Record<K extends keyof any, T> = { [P in K]: T; };
作用:它用來生成一個屬性為 K,屬性值型別為 T 的型別集合。
案例:
const obj: Record<string, string> = { 'name': '張三', 'tag': '打工人' } // 正確 const obj1: Record<'a', string> = { 'a': '453' } // 正確 const obj2: Record<'a', string> = { 'b': '453' } //錯誤 obj2中沒有屬性a
3、Required
原始碼實現:
type Required<T> = { [P in keyof T]-?: T[P]; };
作用:它的作用正好和上面的Partial
相反,是將 T 中的所有屬性都變成必選的狀態。
案例:
interface IFoo { a?: number b?: number } const a: Required<IFoo> = { a: 2, b: 3 } interface IFoo1 { a: number b?: number } const b: Required<IFoo1> = { a: 3, b: 3 }
4、Readonly
原始碼實現:
type Readonly<T> = { readonly [P in keyof T]: T[P]; };
作用:這個從字面意思就可以理解是將一個型別的所有成員變為只讀的狀態。
案例:
interface IFoo { name: string age: number } let a:Readonly<IFoo> = { name: '張三', age: 23 } a.age = 24 // 報錯,age是隻讀屬性
5、Pick
原始碼實現:
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
作用:它的作用是從 T 中將所有的 K 取出來,並生成一個新的型別。
案例:
interface IFoo { name: string age: number height: number } let a:Pick<IFoo,'name'|'age'> = { name: '張三', age: 23 } // 正確。a包含屬性name和age let b:Pick<IFoo,'name'|'age'> = { name: '張三', height: 163 } // 報錯。a只包含屬性name和age,不包含屬性height
6、Exclude
原始碼實現:
type Exclude<T, U> = T extends U ? never : T;
作用:從 T 中排除掉所有包含的 U 屬性。
案例:
// 相當於: type A = 'a' type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'> let a: A = 'a' // 正確 let b: A = 'x' // 不能將型別“"x"”分配給型別“"a"” let c: A = 'l' // 不能將型別“"l"”分配給型別“"a"”
7、Extract
原始碼實現:
type Extract<T, U> = T extends U ? T : never;
作用:正好和上面的Exclude
相反。而是從 T 中提取出所有包含的 U 屬性值。
案例:
// 相當於: type A = 'x' type A = Extract<'a' | 'x', 'x' | 'y'> let a: A = 'x' // 正確 let b: A = 'a' // 報錯:不能將型別“"a"”分配給型別“"x"” let c: A = 'y' // 報錯:不能將型別“"y"”分配給型別“"x"”
8、NonNullable
原始碼實現:
type NonNullable<T> = T extends null | undefined ? never : T;
作用:去除 T 中包含的null
或者undefined
。
案例:
type A = NonNullable<string | null | undefined> let a: A = '李四' // 正確 let b: A = 3 // 報錯:不能將型別“number”分配給型別“string” let c: A = undefined // 報錯: 不能將型別“undefined”分配給型別“string”。
9、Parameters
原始碼實現:
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
作用:用來獲取一個函式的引數型別,而且返回的是隻能包含一組型別的陣列。
案例:
type Func = ({ user: string, age: number }) => void type Param = Parameters<Func> // 等價與type Param = [{user: any;age: any;}] let a: Param = [{ user: '1', age: 34 }] // 正確 let b: Param = [{ user: '1', age: 34, height: 45 }] // 報錯 let c: Param = [{ user: '1', age: 34,},{ user: '1', age: 34,}] // 報錯
10、ConstructorParameters
原始碼實現:
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
作用:用來獲取一個類的建構函式引數型別,並以陣列的形式返回。
案例:
class Person { constructor(name: string, age: number) { } } let a: ConstructorParameters<typeof Person> // 相當於 let a: [name: string, age: number] a = ['張三', 34]
11、ReturnType
原始碼實現:
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
作用:用來得到一個函式的返回值型別。
案例:
type Func = ({ user: string, age: number }) => string type Param = ReturnType<Func> // 相當於: type Param = string let a:Param = undefined // 報錯 不能將型別“undefined”分配給型別“string”。 let b:Param = '3' // 正確 let c:Param = null // 報錯 不能將型別“null”分配給型別“string”。 let d:Param = 2 // 報錯 不能將型別“number”分配給型別“string”。
12、InstanceType
原始碼實現:
type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
作用:獲取一個類的例項型別,可以用獲取到的例項型別來約束一個變數的賦值必須和類的成員型別完全一樣才可以。
案例:
class Person { name: string age: number getName() { return this.name } } let a: InstanceType<typeof Person> = { name: '李四', age: 34, getName() { return '' } }
13、Omit
原始碼實現:
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
作用:用來忽略 T 中的 K 屬性
案例:
type Person = { name: string age: number } let a: Omit<Person, 'name'> = { age: 34 } // 正確 let b: Omit<Person, 'name'> = { height: 34 } // 報錯,b只包含屬性age