[ts]工具类型

38 阅读3分钟

官网链接

Awaited<Type>

await异步返回值类型

// type A = string
type A = Awaited<Promise<string>>;

// type B = number
type B = Awaited<Promise<Promise<number>>>;

// type C = number | boolean
type C = Awaited<boolean | Promise<number>>;
/**
 * Recursively unwraps the "awaited type" of a type. Non-promise "thenables" should resolve to `never`. This emulates the behavior of `await`.
 */
type Awaited<T> =
    // special case for `null | undefined` when not in `--strictNullChecks` mode
    T extends null | undefined ? T : 
        // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
        T extends object & { then(onfulfilled: infer F, ...args: infer _): any } ?
            // if the argument to `then` is callable, extracts the first argument
            F extends ((value: infer V, ...args: infer _) => any) ?
                // recursively unwrap the value
                Awaited<V> :
                // the argument to `then` was not callable
                never : 
        // non-object or non-thenable
        T;

Partial<Type>

指定类型所有属性设为可选

interface Todo {
  title: string;
  description: string;
}

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

Required<Type>

指定类型所有属性设为必须

interface Props {
    a?: number;
    b?: string;
}

const obj: Props = { a: 5 };
// Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.
const obj2: Required<Props> = { a: 5 };
/**
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};

Readonly<Type>

指定类型所有属性设为只读

interface Todo {
    title: string;
}

const todo: Readonly<Todo> = {
    title: "Delete inactive users",
};
// Cannot assign to 'title' because it is a read-only property.
todo.title = "Hello";
/**
 * Make all properties in T readonly
 */
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

Record<Keys, Type>

构造一个对象类型,它的键值是Keys,属性值是Type

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

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

const cats: Record<CatName, CatInfo> = {
    miffy: { age: 10, breed: "Persian" },
    boris: { age: 5, breed: "Maine Coon" },
    mordred: { age: 16, breed: "British Shorthair" },
};
/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

Pick<Type, Keys>

构造一个类型,选择Keys中的属性

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

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
    title: "Clean room",
    completed: false,
};
/**
 * 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];
};

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

Exclude<UnionType, ExcludedMembers>

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

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

// type T2 = string | number
type T2 = Exclude<string | number | (() => void), Function>;
/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

Extract<Type, Union>

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

// type T1 = () => void
type T1 = Extract<string | number | (() => void), Function>;
/**
 * Extract from T those types that are assignable to U
 */
type Extract<T, U> = T extends U ? T : never;

NonNullable<Type>

// type T0 = string | number
type T0 = NonNullable<string | number | undefined>;

// type T1 = string[]
type T1 = NonNullable<string[] | null | undefined>;
/**
 * Exclude null and undefined from T
 */
type NonNullable<T> = T & {};

Parameters<Type>

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

// type T1 = [s: string]
type T1 = Parameters<(s: string) => void>;
/**
 * 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;

ConstructorParameters<Type>

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

ReturnType<Type>

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

InstanceType<Type>

class C {
    x = 0;
    y = 0;
}

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

ThisParameterType<Type>

function toHex(this: number) {
    return this.toString(16);
}


function numberToString(n: ThisParameterType<typeof toHex>) {
    return toHex.apply(n);
}

OmitThisParameter<Type>

function toHex(this: Number) {
    return this.toString(16);
}

const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(5);
console.log(fiveToHex());
/**
 * Removes the 'this' parameter from a function type.
 */
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;

ThisType<Type>

/**
 * Marker for contextual 'this' type
 */
interface ThisType<T> { }

Intrinsic String Manipulation Types

/**
 * Convert string literal type to uppercase
 */
type Uppercase<S extends string> = intrinsic;

/**
 * Convert string literal type to lowercase
 */
type Lowercase<S extends string> = intrinsic;

/**
 * Convert first character of string literal type to uppercase
 */
type Capitalize<S extends string> = intrinsic;

/**
 * Convert first character of string literal type to lowercase
 */
type Uncapitalize<S extends string> = intrinsic;