TypeScript Exclude 怎么用
你有没有过这种经历?写 JavaScript 代码时,想从一个对象类型里去掉几个不想要的属性,结果只能手动重写类型,不仅麻烦还容易写错?其实 TypeScript 自带的 Exclude 类型,就是帮你解决这类问题的“类型清理小工具”。它用法简单,还能省下不少重复劳动,今天就用生活化的例子把它讲明白。
先搞懂:Exclude 到底是啥?
简单说,Exclude 是 TypeScript 里一个内置的“类型筛选工具”,作用是从你给的第一个类型里,排除掉第二个类型里的所有成员,剩下的就是你要的新类型。打个比方:你买了一盒混合糖(第一个类型),里面有水果糖、奶糖、巧克力糖,你只想留下水果糖,把另外两种挑出去,这时候 Exclude 就能帮你把“不想要的糖”筛掉,只留下你要的那部分。

它的写法也很直白,基本格式是:Exclude<要处理的类型, 要排除的类型>,是不是和“从A里排除B”的逻辑完全对应?
用第一个例子:从联合类型里挑想要的
联合类型就是用 | 连起来的几个类型,比如你要做一个天气小程序,可能定义了一个类型来表示不同的天气状态:
`typescript
type Weather = '晴天' | '雨天' | '阴天' | '下雪天';
`
现在你要写一个“户外摆摊”的功能,显然雨天、阴天、下雪天都不适合,只想要晴天。用 Exclude 就能直接搞定,不用重新写一遍新类型:
`typescript
type GoodWeather = Exclude<Weather, '雨天' | '阴天' | '下雪天'>;
// 这时候 GoodWeather 就等于 '晴天',只剩你要的那个类型了
`
要是不用 Exclude,你可能得手动写 type GoodWeather = '晴天',要是后面Weather变了,比如加了“大风天”,你还得同步改GoodWeather,很容易漏。用了Exclude,只要改一次Weather,剩下的筛选自动更新,再也不会忘改了。
用第二个例子:从对象类型里排除属性?不对,别搞错用法
这里要提醒一个容易踩的坑:很多人会误以为Exclude能直接从对象类型里删属性,比如想从type User = {name: string; age: number; password: string}里去掉password属性,直接写Exclude<User, 'password'>,结果会报错。
为什么?因为Exclude只能处理联合类型(就是那种用|连起来的、一个一个的小类型,比如'晴天'|'雨天'),不能直接处理整个对象类型。如果要删对象的属性,得用另一个工具Omit(这个可以记一下,和Exclude对应,一个管联合类型,一个管对象属性),用法是Omit<User, 'password'>,这样就会得到{name: string; age: number},刚好去掉密码属性。
不过Exclude也能间接帮上忙:如果你先把对象的属性名拿出来组成联合类型,再用Exclude排除,最后再拿剩下的属性,虽然麻烦点,但也是可行的。不过日常写代码时,遇到对象删属性直接用Omit就好,Exclude还是留着给联合类型用更合适。
实际开发里的小妙用
除了上面的例子,Exclude还能帮你做一些更实用的事:比如你写了一个按钮组件,支持primary、secondary、danger三种样式,但有个需求是“普通按钮”不能用danger样式,这时候可以用Exclude生成允许的样式类型,避免写错:
`typescript
type ButtonStyle = 'primary' | 'secondary' | 'danger';
type NormalButtonStyle = Exclude<ButtonStyle, 'danger'>;
// 这样你写按钮样式时,TypeScript会自动提示不能选'danger',避免写错
`
还有,当你调用后端接口,返回的字段里有一些临时用的字段(比如tempId),但前端存数据时不需要,这时候可以用Exclude从接口返回的联合类型里把临时字段去掉,得到需要的类型,不用手动重写所有字段。
其实Exclude的核心逻辑就是“筛掉不想要的”,只要记住它只能处理联合类型,不能直接删对象属性,日常开发里用它处理状态、枚举值这类联合类型的场景,基本都够用了,能帮你少写很多重复的类型代码,减少错误。