TypeScript 如何做工具类型封装

在前端开发中,写TypeScript代码时,你是不是经常会碰到“明明类型定义很全,可复用性却很差”的问题?比如写一个“必填字段”的类型,另一个场景又要“部分可选”,还要重复写相似的逻辑,越写越乱。其实TypeScript自带的工具类型,就是帮你解决这类问题的“偷懒神器”,而封装这些工具类型,更是能让你的代码整洁好维护。

先搞懂:工具类型不是“黑魔法”,就是类型的“变形器”

很多人觉得工具类型是复杂的语法,其实它就像你家里的多功能料理机——把一个“原食材”(比如普通的对象类型)放进去,按个键就能变出你要的“成品”(比如只保留需要的字段、把字段变成可选)。举个生活化的例子:你有一张“全家购物清单”,上面有蔬菜、水果、零食、日用品;如果要做“减肥餐清单”,就把“零食”这一行划掉;要做“应急采购清单”,就把所有字段改成“可选”(缺啥买啥),这就是工具类型在做的事:基于原有类型,按需裁剪、变形。

TypeScript 如何做工具类型封装

TypeScript已经自带了一些基础工具类型,比如Partial(把所有字段变可选)、Pick(选部分字段),但这些自带的工具可能没法完全匹配你的项目需求,这时就需要自己封装工具类型了。

封装第一步:用基础工具拼出你要的“定制化类型”

先从最简单的场景入手,比如你做电商项目,有个用户基础类型:

`typescript

type User = {

id: number;

name: string;

age: number;

phone: string;

address: string;

}

`

现在有两个场景:一个是“用户注册”,不需要id(后台自动生成);另一个是“修改用户信息”,所有字段都要可选(只改要改的)。如果重复写类型,会很麻烦,这时可以用基础工具封装:

`typescript

// 封装“去掉id字段的注册类型”

type RegisterUser = Omit<User, 'id'>;

// 封装“所有字段可选的修改类型”

type UpdateUser = Partial<User>;

`

是不是很简单?就像你用料理机把“购物清单”去掉“日用品”,再把剩下的字段变“可选”,一步到位。

封装进阶:处理“特殊需求”,让工具类型更灵活

如果你的需求是“去掉所有带‘id’后缀的字段”,自带的Pick、Omit做不到,就需要自己封装工具类型。这时候要用到TypeScript的“类型遍历”能力,用一句通俗的话讲:就是“把类型里所有字段挨个过一遍,挑符合条件的留下”。

比如封装“去掉带指定后缀字段”的工具:

`typescript

type OmitBySuffix<T, Suffix extends string> = {

// 遍历T的所有字段Key

[K in keyof T as K extends ${infer _}${Suffix} ? never : K]: T[K]

}

`

还是用购物清单举例:如果要去掉所有带“零食”后缀的项,这个工具就会把所有Key挨个检查,只要是带“零食”的,就直接跳过,剩下的保留。用这个工具,就能快速生成你需要的类型,不用再手动一个个写。

封装的核心:让类型“能复用、好维护”

很多人封装工具类型,容易陷入“为了封装而封装”,其实核心是贴合你的项目场景。比如你做后台管理系统,经常要用到“分页查询的请求参数”,可以封装一个通用的分页参数工具:

`typescript

type PaginationParams<T> = {

page: number;

pageSize: number;

filters: Partial<T>;

}

`

这个工具可以复用在商品列表、用户列表、订单列表等所有分页场景,只要把具体的筛选类型传进去就行,就像你买了一个“通用收纳盒”,可以用来放衣服、放玩具、放书籍,不用每次买新的。

最后要注意,封装工具类型不用追求“大而全”,先解决当前项目里的重复类型问题,再慢慢优化。就像你先买一个小收纳盒放桌面,觉得不够用再买大的,而不是一开始就买个巨型的,浪费空间。这样封装出来的工具类型,不仅能减少重复代码,还能让你的TypeScript类型更清晰,维护起来也更轻松。

上一篇 PHP 如何做微信登录