[TypeScript] Utility Types 工具类型 (一)

267 阅读2分钟

一、简介

TS官方提供了一些工具类型便于类型转换,这些工具类型在代码中可以直接使用。 

官网文档

二、工具类型

2.1 Partial<Type> 部分类型

简介:将原类型中的属性全部变成可选的。
/**
 * 源码实现
 * Make all properties in T optional
 */
type Partial<T> = {
    [P in keyof T]?: T[P];
};
// 示例
interface User {
    name:string;
    age:number;
    sex:string;
}

// Partial<User>等价于
interface PartialUser {
    name?:string;
    age?:number;
    sex?:string;
}

function updateUser(user:User,userInfo:Partial<User>):User{
    return {
        ...user,
        ...userInfo
    }
}

2.2 Required<Type> 必须类型

简介:此类型作用与Partial相反,将原类型中的属性全部变成必选的。
/**
 * 源码实现
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};
interface User {
    name:string;
    age?:number;
    sex?:string;
}

// Required<User> 等价于
interface RequiredUser {
    name:string;
    age:number;
    sex:string;
}

function completeUserInfo(user:User,requiredUserInfo:Required<User>):User{
    return {
        ...user,
        ...requiredUserInfo
    }
}

2.3 Readonly<Type> 只读类型

简介:将原类型中的所有属性设置成只读的。
/**
 * 源码实现
 * Make all properties in T readonly
 */
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};
// 示例
interface User {
    name:string;
    age?:number;
    sex?:string;
}

// Required<User> 等价于
interface RequiredUser {
    readonly name:string;
    readonly age?:number;
    readonly sex?:string;
}

const admin:Readonly<User> = {
    name:"admin",
    age:0,
} 

// Cannot assign to 'name' because it is a read-only property.
admin.name = 'hacker'

2.4 Record<Keys, Type> 记录类型

简介:生成一个类型,属性键为keys,属性值为Type类型
/**
 * 源码实现
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};
// 示例
interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<string, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
};
 
cats.tommy = {
    age:3,
    breed:'British Shorthair'
}

2.5 Extract<Type, Union> 提取类型

简介:从UnionType中提取部分选项(该选项是可赋值给ExcludedMembers类型的),生成一个新的类型
/**
 * 源码实现
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;
// 示例
type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// type T0 = "a"

type T1 = Extract<string | number | (() => void), Function>;
// type T1 = () => void

2.6 Exclude<UnionType, ExcludedMembers> 排除类型

简介:从UnionType中排除掉部分选项(该选项是可赋值给ExcludedMembers类型的),生成一个新的类型
/**
 * 源码实现
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;
// 示例
type T0 = Exclude<"a" | "b" | "c", "a">;
// type T0 = "b" | "c"

type T1 = Exclude<"a" | "b" | "c", "a" | "b">;
// type T1 = "c"

type T2 = Exclude<string | number | (() => void), Function>;
// type T2 = string | number

2.7 Pick<Type, Keys> 挑选部分类型

简介:从Type中挑选部分属性,形成一个新的类型
/**
 * 源码实现
 * 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 User {
    name:string;
    age?:number;
    sex?:string;
}

// Pick<User,'age'|'sex'>等同于
interface PickAgeAndSex {
     age?:number;
     sex?:string;
}

function updateUserAgeAndSex(user:User,userInfo:Pick<User,'age'|'sex'>):User{
    return {
        ...user,
        ...userInfo
    }
}

updateUserAgeAndSex({
    name:'wang'
},{
    age:20
})

2.8 Omit<Type, Keys> 忽略部分类型

简介:从Type中删除部分属性,生成一个新的类型;与Pick类型的作用相反。
/**
 * 源码实现
 * 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 User {
    readonly name:string;
    age?:number;
    sex?:string;
}

// Omit<User,'name'>等同于
interface PickAgeAndSex {
     age?:number;
     sex:string;
}

function updateUser(user:User,userInfo:Omit<User,'name'>):User{
    return  {
        ...user,
        ...userInfo
    }
}
let wang:User= {
    name:"xiaowang",
    age:-1
}
wang = updateUser(wang,{
    age:10
})