TS提供的一些实用工具类型

TypeScript提供了几种有用的工具类型,以便于进行常见的类型转换。这些工具类型在全局可用。

长时间不用,有时候就忘记了, 每次都去官网查看比较麻烦, 特在此记录一份,便于查阅。

Awaited<Type>

用来获取 Promise 返回的类型

看官方的例子

js 复制代码
type A = Awaited<Promise<string>>;
// 直接得到 string 类型
type A = string

// 支持递归解析
type B = Awaited<Promise<Promise<number>>>;
type B = number

type C = Awaited<boolean | Promise<number>>;
type C = number | boolean

Partial<Type>

将 type 类型的所有属性变为可选, 比较常用。

js 复制代码
interface Todo {
  title: string;
  description: string;
}
 
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
  return { ...todo, ...fieldsToUpdate };
}
 
const todo1 = {
  title: "organize desk",
  description: "clear clutter",
};
 
const todo2 = updateTodo(todo1, {
  description: "throw out trash",
});

Required<Type>

Partial 相反, 将 Type 类型的所有属性转为必须有。

js 复制代码
interface Props {
  a?: number;
  b?: string;
}
 
const obj: Props = { a: 5 };

// 会报错 缺失了 b 属性
const obj2: Required<Props> = { a: 5 };

Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'.

// 正确
const obj2: Required<Props> = { a: 5, b: '123' };

Readonly<Type>

将 Type 的所有属性标记为只读属性

js 复制代码
interface Todo {
  title: string;
}
const todo: Readonly<Todo> = {
  title: "Delete inactive users",
};

// 报错 属性 title 是只读的 不能修改
todo.title = "Hello";

Record<Keys, Type>

创建一个对象类型, 对象的键是 keys 中的 key, 值是 type 类型 keys 可以是对象属性, 所以只能是 string number symbol 类型

js 复制代码
const objRecord: Record<6, string> = {
  6: 'xxx'
};

官方示例

js 复制代码
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" },
};

Pick<Type, Keys>

从 type 中提取 keys 属性,生成一个新的类型

可以类比 lodash 中的 pick 方法,从一个对象中提取 keys 中的属性,形成一个新对象。

js 复制代码
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

Omit<Type, Keys>

与 Pick 相反, 从 Type 类型中移除 keys 中的属性, 剩下的形成一个新的类型。

js 复制代码
interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}

// 将 description 移除 生成一个新的类型
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  createdAt: 1615544252770,
};

// 移除 completed、createdAt 两项生成新的类型
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
const todoInfo: TodoInfo = {
  title: "Pick up kids",
  description: "Kindergarten closes at 5pm",
};

Exclude<UnionType, ExcludedMembers>

从 UnionType 中 排除 ExcludedMembers 中的类型,生成新的类型。 可以理解为取差集。 注意 ExcludedMembers 描述的是一类 如果有多个符合,都会排除。

js 复制代码
type T0 = Exclude<"a" | "b" | "c", "a">;
// T0 实际的类型
type T0 = "b" | "c"

type T1 = Exclude<"a" | "b" | "c", "a" | "b">;
// T1 实际的类型
type T1 = "c"


type T2 = Exclude<string | number | (() => void), Function>;
// T2 实际的类型
type T2 = string | number
// 这里要注意 Function 描述的是一类。 T22 还是 string | number
type T22 = Exclude<string | number | (() => void) | ((a: string) => void), Function>;
 
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };
 
type T3 = Exclude<Shape, { kind: "circle" }>
// T3 实际的类型  
type T3 = {
    kind: "square";
    x: number;
} | {
    kind: "triangle";
    x: number;
    y: number;
}

Extract<Type, Union>

从 Type 中取出 Union 中提供的类型且在 Type 中存在的 形成新类型, 其实就是取交集。

js 复制代码
type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// T0 实际类型   
type T0 = "a"

type T1 = Extract<string | number | (() => void), Function>;
// T1 实际类型   
type T1 = () => void
 
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; x: number }
  | { kind: "triangle"; x: number; y: number };
 
type T2 = Extract<Shape, { kind: "circle" }>
// T2 实际类型
type T2 = {
    kind: "circle";
    radius: number;
}

NonNullable<Type>

从 Type 中排除 unll 和 undefined,生成新类型

js 复制代码
type T0 = NonNullable<string | number | undefined>;
// T0 实际类型
type T0 = string | number

type T1 = NonNullable<string[] | null | undefined>;
// T1 实际类型
type T1 = string[]

Parameters<Type>

使用函数的参数类型生成元祖类型。

js 复制代码
declare function f1(arg: { a: number; b: string }): void;
 
type T0 = Parameters<() => string>;
// T0 实际的类型
type T0 = []

type T1 = Parameters<(s: string) => void>;
// T1 实际的类型
type T1 = [s: string]

type T2 = Parameters<<T>(arg: T) => T>;
// T2 实际的类型
type T2 = [arg: unknown]

type T3 = Parameters<typeof f1>;
// T3 实际的类型
type T3 = [arg: {
    a: number;
    b: string;
}]

type T4 = Parameters<any>;
// T4 实际的类型
type T4 = unknown[]

type T5 = Parameters<never>;
// T5 实际的类型
type T5 = never

type T6 = Parameters<string>;
Type 'string' does not satisfy the constraint '(...args: any) => any'.
类型"string"不满足约束"(...args: any) => any"
// T6 实际的类型
type T6 = never

type T7 = Parameters<Function>;
Type 'Function' does not satisfy the constraint '(...args: any) => any'.
  Type 'Function' provides no match for the signature '(...args: any): any'.
类型"Function"不满足约束"(...args: any) => any"。
  类型"Function"提供的内容与签名"(...args: any): any"不匹配。
// T7 实际的类型
type T7 = never

ConstructorParameters<Type>

使用构造函数的参数生成元祖或者数组类型

js 复制代码
type T0 = ConstructorParameters<ErrorConstructor>;
// T0 实际的类型
type T0 = [message?: string]

type T1 = ConstructorParameters<FunctionConstructor>;
// T1 实际的类型
type T1 = string[]
           
type T2 = ConstructorParameters<RegExpConstructor>;
// T2 实际的类型
type T2 = [pattern: string | RegExp, flags?: string]

class C {
  constructor(a: number, b: string) {}
}
type T3 = ConstructorParameters<typeof C>;
// T3 实际的类型
type T3 = [a: number, b: string]

type T4 = ConstructorParameters<any>;
// T4 实际的类型
type T4 = unknown[]
 
type T5 = ConstructorParameters<Function>;
Type 'Function' does not satisfy the constraint 'abstract new (...args: any) => any'.
  Type 'Function' provides no match for the signature 'new (...args: any): any'.
类型"Function"不满足约束"abstract new (...args: any) => any"。
  类型"Function"提供的内容与签名"new (...args: any): any"不匹配。
// T5 实际的类型
type T5 = never
相关推荐
安冬的码畜日常8 分钟前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n035 分钟前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。1 小时前
案例-任务清单
前端·javascript·css
zqx_72 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己2 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称3 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2343 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河3 小时前
CSS总结
前端·css
BigYe程普4 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发