Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
简单
Exclude
type MyExclude<T, U> = T extends U ? never : T;
当联合类型作用于泛型的时候,会将每一个类型都分布到该条件判断中。
例如:
type T = MyExclude<"a" | "b" | "c", "a">;
// 执行时大概是这样:
"a" extends "a" ? never : "a" |
"b" extends "a" ? never : "b" |
"c" extends "a" ? never : "c"
// 所以最后 T 的类型就是
type T = "b" | "c"
查阅官方文档请参考分配条件类型。
Awaited
type MyAwaited<T> = T extends Promise<infer U> ? MyAwaited<U> : T;
- 这个没啥好说的,就是通过条件判断加
infer去进行推断 - 需要注意下递归处理
If
type If<C extends boolean, T, F> = C extends true ? T : F;
- 这个也没啥好说的,就是利用条件判断
Concat
type Concat<T extends any[], U extends any[]> = [...T, ...U];
- 因为数组可以拥有
rest元素,详情请看官方文档
Includes
// 判断两个类型是否相等
type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2)
? true
: false;
type Includes<T extends readonly any[], U> =
T extends [infer F, ...infer R]
? Equals<F, U> extends true
? true : Includes<R, U>
: false;
首先来看下Equals类型,可以这么来理解,我通过了一些步骤来演进代码:
type Equals<X, Y> = X extends Y ? true : false;
type T = Equals<true, boolean>;
上面代码中,T的类型会为true,因为boolean类型兼容true类型。
type Equals<X, Y> = (() => X) extends (() => Y) ? true : false;
type T = Equals<true, boolean>;
上面代码中,T的类型还是true,函数的参数和返回值也是存在兼容的,道理和第一个一样的。
所以最后就成这样了:
type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2)
? true
: false;
要把括号括起来的看做是一个整体,一个定义好的类型,例如(<T>() => T extends X ? 1 : 2),所以这时使用extends进行判断的时候,检查会要求类型定义一致,所以就能判断出类型是否相等了。
挑战里测试用例用到的Equal也是这么来判断的。
这时来看看Includes类型,应该好理解很多了。
就是获取数组的第一个元素类型,然后对比是否相等,然后通过递归的方式,把数组中的每一个元素类型都对比了一遍。
答案参考自解答区,然后根据自己的理解,来解释了下,要是有问题,还请大佬们指点一下。