一文读懂TypeScript泛型工具类型-Exclude<T, U>
1. 定义
在 TypeScript 中,泛型工具类型 Exclude<T, U>
主要用于从指定的联合类型 T 中排除指定类型 U。
和泛型工具类型 Extract<T, U>
相反,Extract<T, U>
是用于提取指定的联合类型。
2. 源码
type Exclude<T, U> = T extends U ? never : T;
实现原理:
- 上面这段代码中,使用 type 关键字来定义
Exclude<T, U>
类型,它接收两个类型参数 T 和 U。 T extends U ? never : T
:是一个条件表达式,类似于JS中的三元运算符。这个条件表达式通过检查类型 T 是否可以分配给类型 U 来决定返回的值。如果类型 T 可以分配给类型 U,即 T 是 U 的子类型或等于 U,则返回 never。否则,返回类型 T。- never 是 TypeScript 中的底层类型,表示不可能发生的类型。当条件 T extends U 成立时,意味着类型 T 是可以分配给类型 U 的,因此如果成立,返回 never,表示 T 的类型应该被排除掉。
- 相反,当条件 T extends U 不成立时,意味着类型 T 是不可以分配给类型 U 的,因此返回的是 T 自身,即保留类型 T。
- 通过这样的处理,
Exclude<T, U>
的结果就是从类型 T 中排除了所有可以分配给类型 U 的类型。
下面我们先看下 Exclude<T, U>
的基本用法:
type T1 = string | number | boolean;
type T2 = Exclude<T1, boolean>;
上面这段代码中,我们定义了一个类型 T1,它是由 string、number 和 boolean 组成的联合类型。Exclude<T1, boolean> 表示从指定的联合类型 string | number | boolean 中,剔除掉类型 boolean,返回一个新的类型 T2:string | number。
使用 Exclude<T1, boolean>
创建的新类型 T2,等同于下面的这段代码:
type T2 = string | number;
那么在新类型 T2 中,我们就可以将变量的类型指定为 T2 并赋值,只能赋值 string 类型或者 number 类型,赋值其它类型代码会报错。
type T1 = string | number | boolean;
type T2 = Exclude<T1, boolean>; // 等同于:type T2 = string | number
// 正确
let userName: T2 = "Echo";
let userAge: T2 = 26;
// 报错:不能将类型“boolean”分配给类型“T2”
let isAdult: T2 = false;
3. 使用场景
3.1. 类型过滤
Exclude<T, U>
可以用于从一个联合类型 T 中剔除掉某些类型 U。这在筛选和过滤类型时非常有用,让我们可以选择性地操作类型。
type T1 = "a" | "b" | "c" | "d" | "e";
type T2 = "a" | "c" | "d";
type T3 = Exclude<T1, T2>;
// T3 等同于
// type T3 = "b" | "e"
上面这段代码中,T1 是一个包含5个成员类型的联合类型,T2 是一个包含3个成员类型的联合类型。通过使用 Exclude<T1, T2>,我们从 T1 类型中,把 T2 的3个类型 "a"、"c" 和 "d" 过滤掉了,得到了新的类型 T3,结果为 "b" | "e"。
3.2. 枚举值过滤
当我们有一个枚举类型,并且想要从中排除某些特定值时,可以使用 Exclude<T, U>
。通过排除特定值,我们可以得到一个新的枚举类型,其中不包含被排除的值。
enum Colors {
Red = "RED",
Green = "GREEN",
Blue = "BLUE",
Yellow = "YELLOW",
}
type FilteredColors = Exclude<Colors, Colors.Red | Colors.Green>;
// FilteredColors 等同于:
// Colors.Blue | Colors.Yellow
const blue: FilteredColors = Colors.Blue; // BLUE
const yellow: FilteredColors = Colors.Yellow; // YELLOW
上面这段代码中,我们定义了一个枚举类型 Colors,它包含了四个枚举值。通过使用 Exclude<Colors, Colors.Red | Colors.Green>,我们排除了红色和绿色两个枚举值,得到了一个新的枚举类型 FilteredColors,其中只包含蓝色和黄色。
4. 注意事项
如果 Exclude<T, U>
中泛型参数 U 的类型为 never,则表示不排除任何属性,返回的还是联合类型 T,实际上没有什么意义。
Exclude<T, U>
的泛型参数顺序很重要。第一个参数 T 是要过滤的类型,第二个参数 U 是需要排除的类型。
总结
以上就是我对 TypeScript 中泛型工具类型 Required<T>
的了解,如果有不正确的地方,欢迎大家在评论区多多指正!
看完记得点个赞哦~ 谢谢!🤞🤞🤞
转载自:https://juejin.cn/post/7289336347642249279