简单讲解TS中常用的工具方法Record、Partial 、 Required 、 Readonly、 Pick、Omit

Record

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

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

js 复制代码
Record<key type, value type> 

Record<string, never> 空对象
Record<string, unknown> 任意对象
{} 任何不为空的对象

js 复制代码
type Record<K extends string | number | symbol, T> = {
    [P in K]: T;
}

解析

泛型K即为第一次参数

p in xx 又是什么意思呢?

in的意思就是遍历,如上就是将 类型string进行遍历,也就是string

每个属性都是传入的T类型,如 string: PersonModel

Partial

js 复制代码
type Partial<T> = {
    [P in keyof T]?: Partial<T[P]>
}

作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为可选项

js 复制代码
interface Foo {
    name: string
    age: number
}
type Bar = Partial<Foo>
// 相当于
type Bar = {
    name?: string
    age?: number
}

Required

js 复制代码
type Require<T> = {
    [P in keyof <T>]-?: T[P]
}

作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项

js 复制代码
interface Foo {
    name: string
    age?: number
}
type Bar = Required<Foo>
// 相当于
type Bar = {
    name: string
    age: number
}

Readonly

js 复制代码
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

作用:生成一个新类型,T 中的 K 属性是只读的,K 属性是不可修改的。

js 复制代码
interface Foo {
    name: string
    age: number
}
type Bar = Readonly<Foo>
// 相当于
type Bar = {
    readonly name: string
    readonly age: number
}

Pick

js 复制代码
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

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

js 复制代码
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)

Exclude

js 复制代码
type Exclude<T, U> = T extends U ? never : T

作用:如果 T 是 U 的子类型则返回 never 不是则返回 T

js 复制代码
type A = number | string | boolean
type B = number | boolean

type Foo = Exclude<A, B>
// 相当于
type Foo = string

Extract

js 复制代码
type Extract<T, U> = T extends U ? T : never

作用: 和 Exclude 相反

js 复制代码
type A = number | string | boolean
type B = number | boolean

type Foo = Extract<A, B>
// 相当于
type Foo = number | boolean

Omit

js 复制代码
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>> 

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

js 复制代码
type Foo = {
	name: string
	age: number
}

type Bar = Omit<Foo, 'age'>
// 相当于
type Bar = {
	name: string
}

NonNullable

js 复制代码
NonNullable<T>

作用:从泛型 T 中排除掉 null 和 undefined

js 复制代码
type NonNullable<T> = T extends null | undefined ? never : T;

type t = NonNullable<'name' | undefined | null>;
/* type t = 'name' */

Parameters

js 复制代码
Parameters<T extends (...args: any) => any>

作用:以元组的方式获得函数的入参类型

js 复制代码
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

type t = Parameters<(name: string) => any>; // type t = [string]

type t2 = Parameters<((name: string) => any)  | ((age: number) => any)>; // type t2 = [string] | [number]

ConstructorParameters

js 复制代码
ConstructorParameters<T extends new (...args: any) => any>

作用:以元组的方式获得构造函数的入参类型

js 复制代码
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
 
type t = ConstructorParameters<(new (name: string) => any)  | (new (age: number) => any)>;
// type t = [string] | [number]

ReturnType

js 复制代码
ReturnType<T extends (...args: any) => any>

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

js 复制代码
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

InstanceType

js 复制代码
InstanceType<T extends new (...args: any) => any>

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

js 复制代码
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;
}
*/

总结

1、重点理解这些内置的工具类型的定义。

2、能够以此为参考写一些工具类型并运用到项目中去。

相关推荐
清汤饺子1 小时前
OpenClaw 本地部署教程 - 从 0 到 1 跑通你的第一只龙虾
前端·javascript·vibecoding
颜酱1 小时前
图的数据结构:从「多叉树」到存储与遍历
javascript·后端·算法
爱吃的小肥羊3 小时前
比 Claude Code 便宜一半!Codex 国内部署使用教程,三种方法任选一!
前端
IT_陈寒4 小时前
SpringBoot项目启动慢?5个技巧让你的应用秒级响应!
前端·人工智能·后端
树上有只程序猿5 小时前
2026低代码选型指南,主流低代码开发平台排名出炉
前端·后端
橙某人5 小时前
LogicFlow 小地图性能优化:从「实时克隆」到「占位缩略块」!🚀
前端·javascript·vue.js
高端章鱼哥5 小时前
为什么说用OpenClaw对打工人来说“不划算”
前端·后端
大脸怪5 小时前
告别 F12!前端开发者必备:一键管理 localStorage / Cookie / SessionStorage 神器
前端·后端·浏览器
Mr_Mao5 小时前
我受够了混乱的 API 代码,所以我写了个框架
前端·api
小徐_23335 小时前
向日葵 x AI:把远程控制封装成 MCP,让 AI 替我远程控制设备
前端·人工智能