# 九、工具类型

Typescript 提供了一些工具类型来辅助进行常见的类型转换,这些类型全局可用。

工具方法

# Partial<Type>

用于构造一个Type下面的所有属性都设置为可选的类型,这个工具类型会返回代表给定的一个类型的子集的类型。

type Base = {
    name: string;
    age: number;
};

type _partial = Partial<Base>;
// type _partial = {
//     name?: string | undefined;
//     age?: number | undefined;
// }

// 模拟实现
type _Partial<T> = {
    [K in keyof T]?: T[K];
};

# Required<Type>

用于构造一个Type下面的所有属性全都设置为必填的类型,这个工具类型跟 Partial (opens new window)相反。

type Base = {
    name: string;
    age?: number;
};

type requireBase = Required<Base>;
// type requireBase = {
//     name: string;
//     age: number;
// }

# Readonly<Type>

用于构造一个 Type 下面的所有属性全都设置为只读的类型,意味着这个类型的所有的属性全都不可以重新赋值。

type Base = {
    name: string;
    age?: number;
};

const obj: Readonly<Base> = {
    name: "1",
    age: 100,
};

obj.age = 200; // 无法分配到 "age" ,因为它是只读属性。

type readonlyBase = Readonly<Base>;
// type readonlyBase = {
//     readonly name: string;
//     readonly age?: number | undefined;
// }

type _Readonly<T> = {
    readonly [K in keyof T]: T[K];
};

type readonlyBase2 = _Readonly<Base>;
// type readonlyBase2 = {
//     readonly name: string;
//     readonly age?: number | undefined;
// }

# Record<Keys, Type>

用于构造一个对象类型,它所有的key(键)都是Keys类型,它所有的value(值)都是Type类型。这个工具类型可以被用于映射一个类型的属性到另一个类型。

interface CatInfo {
    age: number;
    breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

// 模拟实现
type _Record<K extends string | number | symbol, T> = {
    [I in K]: T;
};

const cats: Record<CatName, CatInfo> = {
    miffy: { age: 10, breed: "Persian" },
    boris: { age: 5, breed: "Maine Coon" },
    mordred: { age: 16, breed: "British Shorthair" },
};

const cats2: _Record<CatName, CatInfo> = {
    miffy: { age: 10, breed: "Persian" },
    boris: { age: 5, breed: "Maine Coon" },
    mordred: { age: 16, breed: "British Shorthair" },
};

# Pick<Type, Keys> (选择)

顾名思义,返回Type中的部分类型Keys

type Base = {
    name: string;
    age: number;
    height: number;
    weight: number;
};
type keys = 'name' | 'age';

type PickBase = Pick<Base, keys>;
// type PickBase = {
//     name: string;
//     age: number;
// }

// 模拟实现
type _Pick<T, K extends keyof T> = {
    [I in K]: T[I];
};

// 类型“"name" | "aaa"”不满足约束“keyof Base”。
const aaa: _Pick<Base, "name" | "aaa"> = {
    name = "余光",
    aaa = 100,
};

注意 Keys 必须是 Type 的属性,否则就会出现上述报错

# Omit<Type, Keys> (过滤)

用于构造一个类型,它是从Type类型里面过滤了一些属性Keys(Keys是字符串字面量 或者 字符串字面量的联合类型)

interface Todo {
    title: string;
    description: string;
    completed: boolean;
    createdAt: number;
}

type TodoPreview = Omit<Todo, "description">;

const todo: TodoPreview = {
    title: "Clean room",
    completed: false,
    createdAt: 1615544252770,
};

# Exclude<UnionType, ExcludedMembers> (排除)

用于构造一个类型,它是从UnionType联合类型里面排除了所有可以赋给ExcludedMembers的类型。

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

# Extract<Type, Union>(交集)

用于构造一个类型,它是从Type类型里面提取了所有可以赋给 Union 的类型。

type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// type T0 = "a"

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

# Parameters<Type>

用于根据所有 Type 中函数类型的参数构造一个元祖类型。

declare function f1(arg: { a: number; b: string }): void;

type T0 = Parameters<() => string>;
// type T0 = []

type T1 = Parameters<(s: string) => void>;
// type T1 = [s: string]

type T2 = Parameters<<T>(arg: T) => T>;
// type T2 = [arg: unknown]

type T3 = Parameters<typeof f1>;
// type T3 = [arg: {
//    a: number;
//    b: string;
// }]
type T4 = Parameters<any>;
// type T4 = unknown[]

type T5 = Parameters<never>;
// type T5 = never

type T6 = Parameters<string>;
// TypeError: Type 'string' does not satisfy the constraint '(...args: any) => any'.
// type T6 = never

type T7 = Parameters<Function>;
// TypeError: Type 'Function' does not satisfy the constraint '(...args: any) => any'. Type 'Function' provides no match for the signature '(...args: any): any'.
// type T7 = never

# ReturnType<Type>

用于构造一个含有Type函数的返回值的类型。

declare function f1(): { a: number; b: string };

type T0 = ReturnType<() => string>;
// type T0 = string

type T1 = ReturnType<(s: string) => void>;
// type T1 = void

type T2 = ReturnType<<T>() => T>;
// type T2 = unknown

type T3 = ReturnType<<T extends U, U extends number[]>() => T>;
// type T3 = number[]

type T4 = ReturnType<typeof f1>;
// type T4 = {
//    a: number;
//    b: string;
// }

type T5 = ReturnType<any>;
// type T5 = any

type T6 = ReturnType<never>;
// type T6 = never

type T7 = ReturnType<string>;
// TypeError: Type 'string' does not satisfy the constraint '(...args: any) => any'.
// type T7 = any

type T8 = ReturnType<Function>;
// TypeError: Type 'Function' does not satisfy the constraint '(...args: any) => any'. Type 'Function' provides no match for the signature '(...args: any): any'.
// type T8 = any
Last Updated: 2/13/2023, 6:46:24 PM