解决 TS 问题的最好办法就是多练,这次解读 type-challenges Medium 难度 25~32 题。
精读
Diff
实现 Diff<A, B>,返回一个新对象,类型为两个对象类型的 Diff:
type Foo = {
name: string
age: string
}
type Bar = {
name: string
age: string
gender: number
}
Equal<Diff<Foo, Bar> // { gender: number }
首先要思考 Diff 的计算方式,A 与 B 的 Diff 是找到 A 存在 B 不存在,与 B 存在 A 不存在的值,那么正好可以利用 Exclude<X, Y> 函数,它可以得到存在于 X 不存在于 Y 的值,我们只要用 keyof A、keyof B 代替 X 与 Y,并交替 A、B 位置就能得到 Diff:
// 本题答案
type Diff<A, B> = {
[K in Exclude<keyof A, keyof B> | Exclude<keyof B, keyof A>]:
K extends keyof A ? A[K] : (
K extends keyof B ? B[K]: never
)
}
Value 部分的小技巧我们之前也提到过,即需要用两套三元运算符保证访问的下标在对象中存在,即 extends keyof 的语法技巧。
AnyOf
实现 AnyOf 函数,任意项为真则返回 true,否则返回 false,空数组返回 false:
type Sample1 = AnyOf<[1, '', false, [], {}]> // expected to be true.
type Sample2 = AnyOf<[0, '', false, [], {}]> // expected to be false.
本题有几个问题要思考:
第一是用何种判定思路?像这种判断数组内任意元素是否满足某个条件的题目,都可以用递归的方式解决,具体是先判断数组第一项,如果满足则继续递归判断剩余项,否则终止判断。这样能做但比较麻烦,还有种取巧的办法是利用 extends Array<> 的方式,让 TS 自动帮你遍历。
第二个是如何判断任意项为真?为真的情况很多,我们尝试枚举为假的 Case:0 undefined '' undefined null never []。
结合上面两个思考,本题作如下解答不难想到:
type Falsy = '' | never | undefined | null | 0 | false | []
type AnyOf<T extends readonly any[]> = T extends Falsy[] ? false : true
但会遇到这个测试用例没通过:
AnyOf<[0, '', false, [], {}]>
如果此时把 {} 补在 Falsy
精读TypeScript挑战

本文深入探讨了TypeScript挑战中的几道中等难度题目,包括Diff、AnyOf、IsUnion等,通过实战演练提高理解与运用TS高级特性的能力。
最低0.47元/天 解锁文章
1030

被折叠的 条评论
为什么被折叠?



