TypeScript【一】内置工具类型使用及介绍

63 阅读3分钟

1. Omit 省略/剔除

顾名思义 可以剔除 已定义对象中 自己不需要的一部分形成新的定义类型。

源码定义

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>

作用:生成一个新类型,该类型拥有 T 中除了 K 属性以外的所有属性; Exclude<keyof T, K> => 过滤掉 T中的 K属性

interface UserObj {
    name: string; 
    age: number;
    id: number;
    sex: 0 | 1;
    address: string;
    weight: number;
}

// 剔除省略自己不需要的
type Person = Omit<UserObj, "age" | "sex"  | "address" | "weight">;

// 此时Person 等同于 Person1

interface Person1 {
    name: string;
    id: number;
}

const obj:Person = {
    name: '555',
    id: 20
}


2. Pick 采集

顾名思义,可以采集 已定义对象中 自己需要的一部分形成新的定义类型。

源码定义

type Pick<T, K extends keyof T> = { [P in K]: T[P]; };

作用:生成一个新类型,映射类型 ; P in K 类似于 js的 for…in语句 ; extends 为泛型约束

interface Foo {
    name: string;
    age?: number;
    gender: string;
}
type Bar = Pick<Foo, 'age' | 'gender'>
// 相当于
type Bar = {
    age?: number
    gender: string
}

const todo: Bar= {
   age?: 3,
   gender: 男
};
console.log(todo)

3. Partial

可把定义好的对象(包含 必选+可选项)类型全部转化为可选项

源码定义

type Partial<T> = { [P in keyof T]?: T[P]; };

// 已有定义类型Person
interface Person {
    name: string;
    age: number;
    id: number;
    sex: 0 | 1;
    address: string;
    weight: number;
}

// 使用方法
const newObj: Partial<Person> = {
    name: '张三' // 假如只需要一项 Partial的便捷性 可以不需要从新定义类型
};

// Partial<Person>等同于 NewPerson
interface NewPerson {
    name?: string;
    age?: number;
    id?: number;
    sex?: 0 | 1;
    address?: string;
    weight?: number;
}

4. Required (必选的)

Required 和 Partial刚好相反,可把定义好的对象(包含 必选+可选项)类型全部转化为 必选项

源码定义

type Required<T> = { [P in keyof T]-?: T[P]; };};

// 已有定义类型Person
interface Person {
    name: string;
    age: number;
    id?: number;
    sex?: 0 | 1;
}

// 使用方法
const newObj: Required<Person> = {
    name: '张三',
    age: 1,
    id: 1,
    sex: 1
};

// Required<Person>等同于 NewPerson
interface NewPerson {
    name: string;
    age: number;
    id: number;
    sex: 0 | 1;
}

5. Readonly (只读的)

Readonly 就是为类型对象每一项添加前缀 Readonly

源码定义

type Readonly<T> = { readonly [P in keyof T]: T[P]; };

interface Person {
    readonly name: string; // 只有这一项有readonly
    age: number;
    id?: number;
}

// 使用方法
const newObj: Readonly<Person> = {
    name: '张三',
    age: 1,
    id: 1
};
// newObj.name = '李四'; // 异常 因为有readonly只读属性,只能初始化声明,不能赋值。

// Readonly<Person> 等同于 NewPerson
interface NewPerson {
    readonly name: string;
    readonly age: number;
    readonly id?: number;
}

6. Extract (提取/包括)

一般用于处理联合类型, Extract 从 T 中提取可分配给 U 的类型

源码定义

type Extract<T, U> = T extends U ? T : never;

// 处理联合类型
type Test1 = '1' | '2' | '3'

const obj: Extract<Test1, '1' | '2'> = '1'; // 1,2 OK 赋值3就会error

// 结果:'a' | 'c'
type StringExtract = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'>
 
// ✅正确
const s1: StringExtract = 'a'
 
// ✅正确
const s2: StringExtract = 'c'
 
// ❌错误
// Type '"f"' is not assignable to type 'StringExtract'.
const s3: StringExtract = 'f'

7. Excluede (排除/不包括)

一般用于处理联合类型, Exclude 从 T 中排除可分配给 U 的类型, 和 Extract 正好相反

源码定义

type Exclude<T, U> = T extends U ? never : T;

// 处理联合类型
type Test1 = '1' | '2' | '3'

const obj: Exclude<Test1, '1' | '2'> = '3'; // 3 OK 赋值1,2就会error

// 结果:'b' | 'd'
type StringExclude = Exclude<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'>
 
// ✅正确
const s1: StringExclude = 'b'
 
// ✅正确
const s2: StringExclude = 'd'
 
// ❌错误
// Type '"f"' is not assignable to type 'StringExclude'.
const s3: StringExclude = 'f'

8. Record

Record 标记对象的属性(key)或者属性值(value)的类型

Record的内部定义,接收两个泛型参数;Record后面的泛型就是对象键和值的类型

作用 : 定义一个对象的 key 和 value 类型

源码定义

type Record<K extends keyof any, T> = { [P in K]: T; };

interface Person {
    name: string
    age: number
    gender?: 'male' | 'female'
    address?: string
}
 
type PersonRecord = Record<string, Person>
 
// ✅正确
const r1: PersonRecord = {
    'p': {
        name: 'Tom',
        age: 23,
    }
}
 
// ❌错误
// Type 'string' is not assignable to type 'Person'.
const r2: PersonRecord = {
    'p': 'Person'
}
 
// ❌错误
// Property 'age' is missing in type ...
const r3: PersonRecord = {
    'p': {
        name: 'Tom',
    }
}

9. ReturnType

作用:获得函数返回值的类型

源码定义

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

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

10. InstanceType

作用:获得构造函数返回值的类型

源码定义

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

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;
}
*/