TypeScript 中的内置工具类型(Utility Type)

TypeScript 中的内置工具类型(Utility Type)

📌 点赞收藏关注不迷路!

TypeScript 为我们提供了非常多 内置的工具类型(Utility Types),让我们在处理对象、联合类型、函数签名时更优雅、更高效。

但是这些工具类型名称看上去有些"玄学"------PartialOmitPickReturnTypeExtract......你是不是也有点傻傻分不清?

今天我们就来由浅入深,一口气讲清楚 TS 最常用的 Utility Types,并结合实际示例告诉你什么时候用、为什么好用、怎么用最妙!


🧭 一、什么是 Utility Type?

Utility Type 是 TypeScript 提供的内置泛型类型,用于在已有类型的基础上快速创建新类型。

💡 类似于 JavaScript 的工具函数(如 map()filter()),这些类型是对类型的"加工"操作。


🛠️ 二、对象类 Utility Types(最常用)


1️⃣ Partial<T> --- 把所有属性变成可选的

ts 复制代码
type User = { name: string; age: number }
type PartialUser = Partial<User>
// => { name?: string; age?: number }

📌 适用场景:表单更新、Patch 请求、不完整数据对象。


2️⃣ Required<T> --- 把所有属性变成必填

ts 复制代码
type OptionalUser = { name?: string; age?: number }
type FullUser = Required<OptionalUser>
// => { name: string; age: number }

📌 适用场景:类型补全,防止使用时忘记字段。


3️⃣ Readonly<T> --- 所有属性变为只读

ts 复制代码
type Config = { baseUrl: string }
const readonlyConfig: Readonly<Config> = { baseUrl: '/api' }
readonlyConfig.baseUrl = '/new' // ❌ 报错

📌 适用场景:保护配置对象、防止被修改。


4️⃣ Pick<T, K> --- 从对象中"挑出"某些属性

ts 复制代码
type User = { name: string; age: number; email: string }
type PublicUser = Pick<User, 'name' | 'email'>
// => { name: string; email: string }

📌 适用场景:从完整对象中筛选用于展示或传输的字段。


5️⃣ Omit<T, K> --- 从对象中"排除"某些属性

ts 复制代码
type InternalUser = Omit<User, 'email'>
// => { name: string; age: number }

📌 适用场景:隐藏敏感字段、不需要的属性。


🧬 三、函数和类型操作类 Utility Types


6️⃣ ReturnType<T> --- 获取函数返回值类型

ts 复制代码
function getUser() {
  return { name: 'Jin', age: 20 }
}

type User = ReturnType<typeof getUser>
// => { name: string; age: number }

📌 适用场景:接口抽取、避免重复声明返回类型。


7️⃣ Parameters<T> --- 获取函数的参数类型元组

ts 复制代码
function add(a: number, b: number): number {
  return a + b
}

type Args = Parameters<typeof add>
// => [number, number]

📌 适用场景:将参数传递给另一个函数时保持一致。


8️⃣ ConstructorParameters<T> --- 构造函数参数类型

ts 复制代码
class Person {
  constructor(public name: string, public age: number) {}
}

type PersonArgs = ConstructorParameters<typeof Person>
// => [string, number]

📌 适用场景:动态实例化类时推导构造函数参数类型。


9️⃣ InstanceType<T> --- 获取构造函数返回的实例类型

ts 复制代码
type PersonInstance = InstanceType<typeof Person>
// => Person

📌 适用场景:统一管理工厂函数或类实例的类型。


🔎 四、联合类型相关 Utility Types


🔟 Exclude<T, U> --- 从 T 中排除可分配给 U 的类型

ts 复制代码
type Status = 'success' | 'error' | 'loading'
type WithoutLoading = Exclude<Status, 'loading'>
// => 'success' | 'error'

📌 适用场景:过滤掉某些不需要的值或状态。


1️⃣1️⃣ Extract<T, U> --- 从 T 中提取可分配给 U 的类型

ts 复制代码
type Result = Extract<Status, 'success' | 'error'>
// => 'success' | 'error'

📌 适用场景:精确匹配子集类型。


1️⃣2️⃣ NonNullable<T> --- 去除 null 和 undefined

ts 复制代码
type Value = string | null | undefined
type CleanValue = NonNullable<Value>
// => string

📌 适用场景:表单值处理、接口响应数据约束。


🧠 五、实际开发中组合使用示例


✅ 表单类型处理(结合 Pick + Partial)

ts 复制代码
type User = { id: string; name: string; age: number; email: string }
type UserForm = Partial<Pick<User, 'name' | 'age' | 'email'>>
// => 可选的 name, age, email 字段(id 被排除)

✅ 接口安全返回(ReturnType + Readonly)

ts 复制代码
function getConfig() {
  return { baseUrl: '/api', retry: 3 }
}

type Config = Readonly<ReturnType<typeof getConfig>>
// 所有字段只读,防止被修改

✅ 函数封装参数提取(Parameters)

ts 复制代码
function apiLogin(username: string, password: string) {}
const loginArgs: Parameters<typeof apiLogin> = ['user', 'pass']

🎯 六、总结:Utility Types 是类型系统的瑞士军刀

类型 作用
Partial 所有字段变为可选
Required 所有字段变为必填
Readonly 所有字段只读
Pick / Omit 选择/排除字段
ReturnType 推导函数返回类型
Parameters 推导函数参数类型
Exclude / Extract 类型集合筛选
NonNullable 去除 null/undefined

它们让类型更灵活、逻辑更清晰、代码更安全,是 TypeScript 高阶开发的基石。


✅ 最后说一句

如果你读完后觉得 Utility Types 没那么神秘了,别忘了给我一个 点赞 + 收藏 + 关注 啊,别等你用的时候再来找这篇文章!

下一篇我可以写:

🧠《10 个你项目里可能漏掉的 TypeScript 技巧》

欢迎留言、发标题,我来继续帮你写教程文!

相关推荐
JieE21214 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
冬奇Lab17 小时前
AI Workflow 定义的四次演进:从 Markdown 到 JS 脚本,再到分布式多 Agent
javascript·人工智能·agent
一颗烂土豆1 天前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
kyriewen1 天前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
weedsfly1 天前
迭代器、生成器与异步迭代——让数据“按需流动”的艺术
前端·javascript
假如让我当三天老蒯1 天前
前端跨域解决方案(学习用)
前端·javascript·面试
铁皮饭盒1 天前
Bun 哪比 Node.js 快?
javascript·后端
JieE2122 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
candyTong2 天前
RTK 技术原理:一次典型会话里,80% 上下文是怎么省下来的
javascript·后端·架构
_柳青杨2 天前
深入理解 JavaScript 事件循环
前端·javascript