TypeScript中是否存在与Exclude相反的Include类型工具?
解答
TypeScript 原生提供了与 Exclude 作用相反的内置工具类型 Extract,专门用于从联合类型中提取指定的目标成员,完全适配你的需求。
基础用法
针对你给出的示例,直接使用 Extract 即可实现预期效果:
type AlphabetLike = 'a' | 'b' | 'c' | 'zeta' | 'beta' | 'gamma' | 'mu'; // 仅保留明确指定的成员,后续AlphabetLike新增无关值不会影响该类型结果 type Alphabet = Extract<AlphabetLike, 'a' | 'b' | 'c'>; // 最终类型等价于 type Alphabet = 'a' | 'b' | 'c'
这种写法刚好解决你提到的两个问题:
- 不需要罗列大量需要排除的成员,只需要明确声明你需要保留的目标成员即可
- 后续如果
AlphabetLike新增不在保留列表里的成员,Alphabet类型不会发生任何非预期变动
目标成员缺失校验
如果你需要在「目标集合中的成员被从AlphabetLike移除」时获得明确的类型提示,可以额外加一层类型约束做校验:
// 统一定义需要保留的目标成员集合 type TargetAlphabetMembers = 'a' | 'b' | 'c'; // 校验所有目标成员都存在于源类型中,缺失时会直接抛出类型错误 type AssertAllMembersExist<Target extends Source, Source> = Target; type _MemberCheck = AssertAllMembersExist<TargetAlphabetMembers, AlphabetLike>; // 提取目标成员得到最终类型 type Alphabet = Extract<AlphabetLike, TargetAlphabetMembers>;
如果后续有人修改AlphabetLike时误删了你需要保留的成员(比如删除了'c'),_MemberCheck所在行就会立刻报类型错误,你可以第一时间感知到异常。
实现逻辑对比
两个互逆的内置工具类型底层实现非常简单,都是基于分布式条件类型:
// 排除源联合类型中属于目标联合的成员 type Exclude<Source, Target> = Source extends Target ? never : Source; // 提取源联合类型中属于目标联合的成员 type Extract<Source, Target> = Source extends Target ? Source : never;
内容的提问来源于stack exchange,提问作者William Neely
相关产品推荐
相关产品推荐

