目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium Promise All
题目要求
import { Equal, Expect } from '@type-challenges/utils'
const promiseAllTest1 = PromiseAll([1, 2, 3] as const)
const promiseAllTest2 = PromiseAll([1, 2, Promise.resolve(3)] as const)
const promiseAllTest3 = PromiseAll([1, 2, Promise.resolve(3)])
type cases = [
Expect<Equal<typeof promiseAllTest1, Promise<[1, 2, 3]>>>,
Expect<Equal<typeof promiseAllTest2, Promise<[1, 2, number]>>>,
Expect<Equal<typeof promiseAllTest3, Promise<[number, number, number]>>>
]
我的答案
declare function PromiseAll<T extends any[] = any[]>(
values: readonly [...T]
): Promise<{ [K in keyof T]: T[K] extends Promise<infer R> ? R : T[K] }>;
知识点
-
关键是values是
readonly [...T],如果是readonly修饰的这样就可以通过...T推断出相关的类型,这个地方就是个联合类型了 -
将一个
any[]转换为一个const在 typescript 类型中的操作为增加 readOnly,就可以将范围缩小 -
当一个数组
readonly的时候,意味着他的顺序是一定的,这个时候也可以使用遍历对象的 mapped 去遍历数组
2. Medium Look Up
题目要求
import { Equal, Expect } from '@type-challenges/utils'
interface Cat {
type: 'cat'
breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}
interface Dog {
type: 'dog'
breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
color: 'brown' | 'white' | 'black'
}
type Animal = Cat | Dog
type cases = [
Expect<Equal<LookUp<Animal, 'dog'>, Dog>>,
Expect<Equal<LookUp<Animal, 'cat'>, Cat>>,
]
我的解答
type LookUp<U extends { type: any }, T> = U extends infer P
? P extends { type: any }
? T extends P["type"]
? P
: never
: never
: never;
知识点:
- 构造一个两个对象的基类,然后用
infer对关键的字段进行判断即可
3. Medium Trim Left
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<TrimLeft<'str'>, 'str'>>,
Expect<Equal<TrimLeft<' str'>, 'str'>>,
Expect<Equal<TrimLeft<' str'>, 'str'>>,
Expect<Equal<TrimLeft<' str '>, 'str '>>,
Expect<Equal<TrimLeft<' \n\t foo bar '>, 'foo bar '>>,
]
我的解答
type TrimLeft<T extends string> = T extends `${infer P}${infer K}`
? P extends " " | "\n" | "\t"
? TrimLeft<K>
: T
: never;
知识点
- TS的递归方式
- 联合类型的判断,也可以通过
extends,学名叫分布式类型判断