目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium Drop Char
题目要求
import { Equal, Expect } from '@type-challenges/utils';
type cases = [
Expect<Equal<DropChar<'butter fly!', ''>, 'butterfly!'>>,
Expect<Equal<DropChar<'butter fly!', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<'butter fly!', '!'>, 'butter fly'>>,
Expect<Equal<DropChar<' butter fly! ', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', ' '>, 'butterfly!'>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', 'b'>, ' u t t e r f l y ! '>>,
Expect<Equal<DropChar<' b u t t e r f l y ! ', 't'>, ' b u e r f l y ! '>>,
]
我的答案
type DropChar<
S,
C extends string,
R extends string = ""
> = S extends `${infer P}${infer K}`
? C extends ""
? `${R}${DropChar<S, " ", R>}`
: P extends C
? `${R}${DropChar<K, C, R>}`
: `${R}${P}${DropChar<K, C, "">}`
: R;
知识点
- 字符串拼接 + 递归
2. Medium Minus One
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<MinusOne<1>, 0>>,
Expect<Equal<MinusOne<55>, 54>>,
Expect<Equal<MinusOne<3>, 2>>,
Expect<Equal<MinusOne<100>, 99>>,
Expect<Equal<MinusOne<1101>, 1100>>,
]
我的解答
type NumberToTuple<
T extends number,
U extends any[] = []
> = U["length"] extends T ? U : NumberToTuple<T, [1, ...U]>;
type MinusOne<
T extends number,
R extends number[] = NumberToTuple<T>
> = R extends [infer P, ...infer X] ? X["length"] : 0;
知识点
- 如果将一个数字扩展成一个数组,使用之前的
length获取数组长度的方法和这个常量的数字通过extends进行比较即可 - 还是利用
length求得-1后的长度 - @todo:目前这个地方超过1000就会溢出了,所以其实写的还是不够完美,后面可以看看其他的更完美的方案
3. Medium Pick By Type
题目要求
import { Equal, Expect } from '@type-challenges/utils'
interface Model {
name: string
count: number
isReadonly: boolean
isEnable: boolean
}
type cases = [
Expect<Equal<PickByType<Model, boolean>, { isReadonly: boolean; isEnable: boolean }>>,
Expect<Equal<PickByType<Model, string>, { name: string }>>,
Expect<Equal<PickByType<Model, number>, { count: number }>>,
]
我的解答
type PickByType<T extends object, U, K extends keyof T = keyof T> = {
[key in K extends K ? (T[K] extends U ? K : never) : never]: U;
};
知识点
- 关键在于如何将一个对象真实的
key过滤出来,那些泛化的[key: string]过滤掉,使用K extends K这种方式