目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium AnyOf
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<AnyOf<[1, 'test', true, [1], {name: 'test'}, {1: 'test'}]>, true>>,
Expect<Equal<AnyOf<[1, '', false, [], {}]>, true>>,
Expect<Equal<AnyOf<[0, 'test', false, [], {}]>, true>>,
Expect<Equal<AnyOf<[0, '', true, [], {}]>, true>>,
Expect<Equal<AnyOf<[0, '', false, [1], {}]>, true>>,
Expect<Equal<AnyOf<[0, '', false, [], {name: 'test'}]>, true>>,
Expect<Equal<AnyOf<[0, '', false, [], {1: 'test'}]>, true>>,
Expect<Equal<AnyOf<[0, '', false, [], {name: 'test'}, {1: 'test'}]>, true>>,
Expect<Equal<AnyOf<[0, '', false, [], {}]>, false>>,
Expect<Equal<AnyOf<[]>, false>>,
]
我的答案
type isEmptyObject<T> = T extends object
? keyof T extends never
? true
: false
: false;
type isTrue<T> = T extends []
? false
: T extends []
? false
: T extends 0
? false
: T extends ""
? false
: T extends false
? false
: isEmptyObject<T> extends true
? false
: true;
type AnyOf<T extends readonly any[], R extends boolean = false> = T extends [
infer P,
...infer K
]
? isTrue<P> extends true
? true
: AnyOf<K, R>
: R;
知识点
- 对于 false 场景的列举
- 对于空对象的判断
- 递归
2. Medium isNever
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<IsNever<never>, true>>,
Expect<Equal<IsNever<never | string>, false>>,
Expect<Equal<IsNever<"">, false>>,
Expect<Equal<IsNever<undefined>, false>>,
Expect<Equal<IsNever<null>, false>>,
Expect<Equal<IsNever<[]>, false>>,
Expect<Equal<IsNever<{}>, false>>,
]
我的解答
type IsNever<T> = (() => T) extends () => never ? true : false;
知识点
- never / false / boolean 这些判断需要额外将其包装成函数/数组才能做判断,单独判断
false extends boolean => true这是判断不出来的
3. Medium isUnion
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<IsUnion<string>, false >>,
Expect<Equal<IsUnion<string|number>, true >>,
Expect<Equal<IsUnion<'a'|'b'|'c'|'d'>, true >>,
Expect<Equal<IsUnion<undefined|null|void|''>, true >>,
Expect<Equal<IsUnion<{a: string}|{a: number}>, true >>,
Expect<Equal<IsUnion<{a: string|number}>, false >>,
Expect<Equal<IsUnion<[string|number]>, false >>,
// Cases where T resolves to a non-union type.
Expect<Equal<IsUnion<string|never>, false >>,
Expect<Equal<IsUnion<string|unknown>, false >>,
Expect<Equal<IsUnion<string|any>, false >>,
Expect<Equal<IsUnion<string|'a'>, false >>,
]
我的解答
type IsUnion<T> = Permutation<T>["length"] extends 1 ? false : true;
知识点
- 全排列数量大于 2 即可,所以参考使用之前的全排列类型即可。