目的
Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~
题目大纲
01. Medium BemStyleString
题目要求
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<BEM<'btn', ['price'], []>, 'btn__price'>>,
Expect<Equal<BEM<'btn', ['price'], ['warning', 'success']>, 'btn__price--warning' | 'btn__price--success' >>,
Expect<Equal<BEM<'btn', [], ['small', 'medium', 'large']>, 'btn--small' | 'btn--medium' | 'btn--large' >>,
]
我的答案
type BEM<
B extends string,
E extends string[],
M extends string[]
> = E["length"] extends 0
? M["length"] extends 0
? B
: M extends (infer P)[]
? P extends string
? `${B}--${P}`
: B
: B
: E extends (infer P)[]
? P extends string
? M["length"] extends 0
? `${B}__${P}`
: M extends (infer R)[]
? R extends string
? `${B}__${P}--${R}`
: B
: B
: B
: B;
知识点
- 各种通过
extends对关键结果进行判断即可 - 通过
length来判断某一个数组为空
2. Medium In Order Traversal
题目要求
import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils'
const tree1 = {
val: 1,
left: null,
right: {
val: 2,
left: {
val: 3,
left: null,
right: null,
},
right: null,
},
} as const
const tree2 = {
val: 1,
left: null,
right: null,
} as const
const tree3 = {
val: 1,
left: {
val: 2,
left: null,
right: null,
},
right: null,
} as const
const tree4 = {
val: 1,
left: null,
right: {
val: 2,
left: null,
right: null
}
} as const
type cases = [
Expect<Equal<InorderTraversal<null>, []>>,
Expect<Equal<InorderTraversal<typeof tree1>, [1, 3, 2]>>,
Expect<Equal<InorderTraversal<typeof tree2>, [1]>>,
Expect<Equal<InorderTraversal<typeof tree3>, [2, 1]>>,
Expect<Equal<InorderTraversal<typeof tree4>, [1, 2]>>,
]
我的解答
interface TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
}
type InorderTraversal<T extends TreeNode | null> = T extends TreeNode
? T["left"] extends never
? [T["val"]]
: T["left"] extends TreeNode
? [
...InorderTraversal<T["left"]>,
T["val"],
...InorderTraversal<T["right"]>
]
: T["right"] extends TreeNode
? [T["val"], ...InorderTraversal<T["right"]>]
: [T["val"]]
: [];
知识点
- 一个关于二叉树的后序遍历,只要知道遍历方法就能做出来~
- 关于类型推断的遍历
3. Medium Flip
题目要求
import { Equal, Expect, NotEqual } from '@type-challenges/utils'
type cases = [
Expect<Equal<{a: 'pi'}, Flip<{pi: 'a'}>>>,
Expect<NotEqual<{b: 'pi'}, Flip<{pi: 'a'}>>>,
Expect<Equal<{3.14: 'pi', true: 'bool'}, Flip<{pi: 3.14, bool: true}>>>,
Expect<Equal<{val2: 'prop2', val: 'prop'}, Flip<{prop: 'val', prop2: 'val2'}>>>,
]
我的解答
type TransKeyToString<T> = T extends boolean | string | number ? `${T}` : "";
type Flip<
T extends object,
K extends keyof T = keyof T,
V extends T[K] = T[K]
> = {
[key in TransKeyToString<V>]: K extends K
? TransKeyToString<T[K]> extends key
? K
: never
: never;
};
知识点
- 如果不想返回某个类型,可以返回never
- 使用
K extends将泛型key删除