目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium Fill
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Fill<[], 0>, []>>,
Expect<Equal<Fill<[], 0, 0, 3>, []>>,
Expect<Equal<Fill<[1, 2, 3], 0, 0, 0>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], 0, 2, 2>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], 0>, [0, 0, 0]>>,
Expect<Equal<Fill<[1, 2, 3], true>, [true, true, true]>>,
Expect<Equal<Fill<[1, 2, 3], true, 0, 1>, [true, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], true, 1, 3>, [1, true, true]>>,
Expect<Equal<Fill<[1, 2, 3], true, 10, 0>, [1, 2, 3]>>,
Expect<Equal<Fill<[1, 2, 3], true, 0, 10>, [true, true, true]>>,
]
我的答案
type Slice<
T extends any[],
Start extends number = 0,
End extends number = T["length"],
R extends any[] = [],
Count extends any[] = []
> = Count["length"] extends T["length"]
? R
: Count["length"] extends End
? R
: Count["length"] extends Start
? Slice<T, Start, End, [...R, T[Start]], [...Count, number]>
: R extends []
? Slice<T, Start, End, R, [...Count, number]>
: Slice<T, Start, End, [...R, T[Count["length"]]], [...Count, number]>;
type FillArray<
N,
Start extends number,
End extends number,
MaxLength extends number,
R extends any[] = [],
Count extends any[] = []
> = Count["length"] extends MaxLength
? R
: Count["length"] extends End
? R
: Count["length"] extends Start
? FillArray<N, Start, End, MaxLength, [N], [...Count, number]>
: R["length"] extends 0
? FillArray<N, Start, End, MaxLength, R, [...Count, number]>
: FillArray<N, Start, End, MaxLength, [...R, N], [...Count, number]>;
type Fill<
T extends unknown[],
N,
Start extends number = 0,
End extends number = T["length"],
StartArray extends any[] = Slice<T, 0, Start>,
EndArray extends any[] = Slice<T, End, T["length"]>,
R extends any[] = FillArray<N, Start, End, T["length"]>
> = GreaterThan<Start, End> extends true
? T
: T extends []
? []
: [...StartArray, ...R, ...EndArray];
知识点
-
这是个综合的题目通过Slice + Array Fill拆解成两个递归来完成这个功能
-
通过之前的GreaterThan来做边界的判断
2. Medium TrimRight
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<TrimRight<'str'>, 'str'>>,
Expect<Equal<TrimRight<'str '>, 'str'>>,
Expect<Equal<TrimRight<'str '>, 'str'>>,
Expect<Equal<TrimRight<' str '>, ' str'>>,
Expect<Equal<TrimRight<' foo bar \n\t '>, ' foo bar'>>,
]
我的解答
type EmptyLetter = " " | "\n" | "\t";
type TrimRight<S extends string> = S extends `${infer P}${EmptyLetter}`
? TrimRight<P>
: S;
知识点
- 之前在Trim中已经介绍过,主要就是拼接字符串的
extends判断
3. Medium Without
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Without<[1, 2], 1>, [2]>>,
Expect<Equal<Without<[1, 2, 4, 1, 5], [1, 2]>, [4, 5]>>,
Expect<Equal<Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>, []>>
]
我的解答
type FormatArray<T> = T extends any[] ? T : [T];
type Without<
T extends any[],
U,
R extends any[] = [],
K extends any[] = FormatArray<U>
> = T extends [infer P, ...infer C]
? Includes<K, P> extends true
? Without<C, U, R>
: Without<C, U, [...R, P]>
: R;
知识点
- 简单的递归 + 对于数组
infer拆分的判断