目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium Chainable Options
题目要求
import { Alike, Expect } from '@type-challenges/utils'
declare const a: Chainable
const result = a
.option('foo', 123)
.option('bar', { value: 'Hello World' })
.option('name', 'type-challenges')
.get()
type cases = [
Expect<Alike<typeof result, Expected>>
]
type Expected = {
foo: number
bar: {
value: string
}
name: string
}
我的答案
type Chainable<T extends object = {}> = {
option<M extends string, V extends any>(
key: M,
value: V
): V extends infer P
? Chainable<
{
[key in M]: P;
} & T
>
: never;
get(): T;
};
这道题目比较难的一点是需要不断的在 option 执行后的内容类似递归一样能够叠加,所以要如何做到呢~
知识点
- 可以增加泛型 + 默认值的方式来扩展字段
- 对于函数的参数,如果需要使用
infer推断,或者要将string类型转换成const这个时候可以将参数搞成泛型,这样就可以用推断的方式来进行操作了
2. Medium Last of array
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Last<[3, 2, 1]>, 1>>,
Expect<Equal<Last<[() => 123, { a: string }]>, { a: string }>>,
]
我的解答
type Last<T extends any[]> = T extends [...any[], infer P] ? P : undefined;
这个题目比较简单,使用...这个扩展运算符即可
3. Medium pop
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Pop<[3, 2, 1]>, [3, 2]>>,
Expect<Equal<Pop<['a', 'b', 'c', 'd', ]>, ['a', 'b', 'c']>>,
]
我的解答
type Pop<T extends any[]> = T extends [...infer P, any] ? P : [];
知识点
- 如果需要推断数组的类型,比如
[1, 2] as const,要直接infer P - 如果想要推断
T[number],数组中索引的每一项,这个时候可以使用(infer P)[]