尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

TypeScript 常用泛型工具函数

TypeScript 常用泛型工具函数
📅 发布时间:2026/7/1 14:48:23

目录

什么是泛型工具类型?

1. 属性修饰符:让类型“变个身”

Partial —— 变“全员可选”

Required —— 变“全员必选”

Readonly —— 变“只读”

2. 结构过滤:像筛子一样筛选类型

Pick —— 只取我要的

Omit —— 排除我不要的

3. 函数类型侦探:提取函数的秘密

Parameters —— 提取参数类型

ReturnType —— 提取返回值类型

4. 映射与构造:快速创建结构

Record —— 键值对工厂

5. 进阶实战:手写自定义工具

实战 1:DeepPartial (深度可选)

实战 2:Get (点符号访问类型)

参考官方文档:

什么是泛型工具类型?

简单来说,泛型工具类型就是用来操作类型的函数。

普通函数是Input -> Output(如map把数组转换成新数组)。
泛型工具类型是Type -> Type(如Partial把所有属性变成可选)。

TypeScript 内置了大量开箱即用的工具类型,覆盖了前端开发 90% 的场景。

1. 属性修饰符:让类型“变个身”

这是最基础也是最高频的一类工具,主要用于修改对象属性的读写性或必选性。

Partial<T>—— 变“全员可选”

场景:当你有一个“编辑用户信息”的表单,用户可能只想修改昵称,不想改头像。你不需要把所有字段都重写一遍。

interface User { id: number; name: string; age: number; avatar: string; } // 场景:定义更新接口,不需要传 id,且其他字段都可选 type UserUpdateForm = Partial<Omit<User, 'id'>>; // 等价于: // type UserUpdateForm = { // name?: string; // age?: number; // avatar?: string; // } function updateUser(id: number, data: UserUpdateForm) { // ... }

Required<T>—— 变“全员必选”

场景:Partial的反操作。比如从后端拿来的配置对象可能有缺省,但在运行时你确保它已经补全了,可以用它断言类型。

Readonly<T>—— 变“只读”

场景:Redux 的 State 或者 Vue/React 的 Props 定义,防止在组件内部意外修改父级传递的数据。

type ReadonlyState = Readonly<{ count: number; }>; // state.count = 2; // ❌ Error: Cannot assign to 'count' because it is read-only

2. 结构过滤:像筛子一样筛选类型

如果你只想从大接口中拿几个字段,或者剔除几个敏感字段,这一类工具是你的救星。

Pick<T, K>—— 只取我要的

场景:后端返回了一个包含 20 个字段的“用户详情”,但你只需要渲染一个“用户卡片”,只需要id,name,avatar。

interface UserDetail { id: number; name: string; email: string; phone: string; passwordHash: string; // 敏感信息 lastLoginIp: string; } // 只需要这三个字段做卡片展示 type UserCardProps = Pick<UserDetail, 'id' | 'name' | 'avatar'>;

Omit<T, K>—— 排除我不要的

场景:创建文章列表,数据结构和创建文章表单几乎一样,但列表不需要content字段(太长了),且不需要id(新建时没有)。

interface Article { id: number; title: string; content: string; tags: string[]; } // 新建文章表单:不需要 id type CreateArticleDto = Omit<Article, 'id'>;

小技巧:Omit其实可以用Pick和Exclude组合实现,但 TS 内置了它,直接用更爽。

3. 函数类型侦探:提取函数的秘密

在编写高阶组件或装饰器时,我们经常需要知道一个函数“接收什么参数”以及“返回什么类型”。

Parameters<T>—— 提取参数类型

场景:你要写一个日志装饰器,包裹任意函数,打印它的参数名和值。

function log<T extends (...args: any[]) => any>(fn: T) { return function(this: any, ...args: Parameters<T>) { console.log('Function called with:', args); return fn.apply(this, args); }; } function add(a: number, b: number) { return a + b; } const wrappedAdd = log(add); // wrappedAdd 的参数类型自动推断为

ReturnType<T>—— 提取返回值类型

场景:异步请求封装时,你想基于 API 函数的返回值定义 Redux 的 Action 类型。

async function fetchUser(id: number): Promise<{ name: string; age: number }> { return { name: 'Jack', age: 18 }; } // 自动推导 fetchUser 返回的 Promise 内部结构 type UserType = Awaited<ReturnType<typeof fetchUser>>; // UserType = { name: string; age: number }

4. 映射与构造:快速创建结构

Record<Keys, Type>—— 键值对工厂

场景:定义一个枚举对象,或者一个以 ID 为 Key 的字典。

// 定义一个角色权限映射 type Role = 'admin' | 'user' | 'guest'; type Permission = { read: boolean; write: boolean; }; // 快速生成对象结构:所有角色的权限列表 type RolePermissions = Record<Role, Permission>; const permissions: RolePermissions = { admin: { read: true, write: true }, user: { read: true, write: false }, guest: { read: false, write: false }, };

5. 进阶实战:手写自定义工具

内置的很好用,但有时候我们需要更强大的功能。通过泛型递归和条件类型,我们可以自己造“轮子”。

实战 1:DeepPartial(深度可选)

内置的Partial只能处理一层。如果对象是嵌套的,我们需要递归地把所有层级的属性都变为可选。

type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; }; interface Config { server: { host: string; port: number; }; db: { name: string; }; } // 现在嵌套属性也是可选的了 type PartialConfig = DeepPartial<Config>; // partialConfig.server?.host // 合法

实战 2:Get(点符号访问类型)

类似 Lodash 的_.get,但是是在类型层面操作。根据字符串路径获取深层属性的类型。

type Get<T, P> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Get<T[K], Rest> : never : P extends keyof T ? T[P] : never; interface ApiData { user: { info: { name: string; }; }; } // 根据路径 'user.info.name' 获取类型 string type UserNameType = Get<ApiData, 'user.info.name'>; // string

参考官方文档:

TypeScript Utility Types 官方文档

相关新闻

  • Unlock-Music:三步解锁音乐自由,告别平台束缚的音乐管理革命
  • 跨境电商防关联浏览器指纹参数如何自动生成?
  • 三年Java开发面试经验:从基础到框架

最新新闻

  • CR2032电池供应商有哪些?国内外主要CR2032生产厂家盘点
  • 2026 TCL华星光电标杆研学参访|全球显示科技智能制造考察预约指南
  • 如何用novelWriter实现高效小说创作:从零到完整作品的完整指南
  • Parsec虚拟显示器:为Windows系统打造完美的屏幕扩展解决方案
  • 告别黑屏切换:Borderless Gaming如何重新定义Windows游戏体验
  • 2026年AI聚合API中转站横评实测:六大平台横向对比,企业级生产环境下该怎么选择API聚合平台?

日新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号