携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
1. 引言
接下来我们将开启新的篇章继续Ts困难篇的题型练习
https://github.com/type-challenges/type-challenges/blob/main/README.zh-CN.md
提供的TypeScript 类型体操姿势合集题型,目的是为了让大家更好的了解TS的类型系统,编写自己的类型工具,或者单纯的享受挑战的乐趣!
2. 题型
- Union to Intersection:实现高级util类型UnionToIntersection
type I = Union2Intersection<'foo' | 42 | true> // expected to be 'foo' & 42 & true
思路: 首先使用类比判断,当入参U 为任意类型时候,判断是否可以作为函数入参,如果可以,使用infer关键字获取到对应回抛参数,抛出值为联合类型。本题结束。 解答:
type UnionToIntersection<U> = (U extends any ? (x:U) => any : never) extends (x:infer A) => any ? A : never
- Get Required:实现高级util类型GetRequired,该类型保留所有必填字段
type I = GetRequired<{ foo: number, bar?: string }> // expected to be { foo: number }
思路: 使用映射类型获取对象对应key值后,Required 判断过滤非必填字段后的属性值,如果是必填则保留,非必填移除;本题结束。 解答:
type GetRequired<T> = {
[P in keyof T as T[P] extends Required<T>[P] ? P : never]: T[P]
}
- Get Optional:实现高级util类型GetOptional,该类型保留所有可选字段
type I = GetOptional<{ foo: number, bar?: string }> // expected to be { bar?: string }
思路: 首先定义过滤非必填字段的Required 事件后,使用映射类型后,断言判断当对象值为必选属性时候,过滤掉该键值,否则保留,该题与 Get Required 互为颠倒;解题完成。 解答:
type Required<T> = { [k in keyof T]-?:T[k] }
// type GetRequired<T> = { [k in keyof T as T[k] extends Required<T>[k] ? k : never]:T[k] }
// type GetOptional<T> = { [k in keyof T as k extends keyof GetRequired<T> ? never : k]:T[k] }
type GetOptional<T> = { [k in keyof T as T[k] extends Required<T>[k] ? never : k]:T[k] }