Ts类型体操Easy部分

简介: Ts类型体操Easy部分

手把手一起完成Ts类型体操中的Easy部分


我们可以先了解一下类型体操的分类

  • 对属性的修饰,包括对象属性和数组元素的可选/必选、只读/可写。我们将这一类统称为属性修饰工具类型
  • 对既有类型的裁剪、拼接、转换等,比如使用对一个对象类型裁剪得到一个新的对象类型,将联合类型结构转换到交叉类型结构。我们将这一类统称为结构工具类型
  • 对集合(即联合类型)的处理,即交集、并集、差集、补集。我们将这一类统称为集合工具类型
  • 基于 infer 的模式匹配,即对一个既有类型特定位置类型的提取,比如提取函数类型签名中的返回值类型。我们将其统称为模式匹配工具类型
  • 模板字符串专属的工具类型,比如神奇地将一个对象类型中的所有属性名转换为大驼峰的形式。这一类当然就统称为模板字符串工具类型了。


实现Pick




type MyPick<T, K> = any

Pick<Type, Keys>用于构造一个类型,它是从Type类型里面挑了一些属性Keys(Keys是字符串字面量 或者 字符串字面量的联合类型), 所以Pick返回的是一个对象。

改写第一步

type MyPick<T, K> = {
}

我们可以从遍历K中的属性名,然后从T中取出相应的类型

image.png

但是现在还是报错的,并且测试用例也没有通过,原因是 T 中可能不存在 K中的相应类型

举个例子, 这时候Todo里面没有 'lesson' 属性,不就报错了吗!,所以我们需要用extends约束一下 K 的类型


interface Todo {
    title: string
    description: string
    completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'| 'lesson'>

答案


type MyPick<T, K extends keyof T> = {
  [Key in K ]: T[Key]
}


实现Readonly



直接遍历T中的属性,然后加上readonly关键字就好了


type MyReadonly<T> = {
  readonly [key in keyof T] :T[key]
}


元组转换为对象



怎么从元组里面拿到所有的类型

Tuple[number]  // 可以获得元组所有类型的组合


type TupleToObject<T extends readonly any[]> = {
  [key in T[number]] : key
}


第一个元素


使用infer关键字,占取第一个元素,并将剩余元素收集起来。 根据测试用例的提示,当数组为空时,返回的是never类型


type First<T extends any[]> = T extends [infer one, ... any[]] ? one : never


获取元素长度



我们可以通过length属性,直接返回元素的长度


type Length<T> = T['length']

但是我们必须要对 T 进行进一步的约束,确保 T 中有length属性


type Length<T extends any[]> = T['length']

但是这时候我们还是报错,说readonly和any[]不匹配,我们要在前面加上readonly即可

image.png


type Length<T extends  readonly any[]> = T['length']


Exclude



前置知识,分发条件类型(Distributive Conditional Types)

当在泛型中使用条件类型时,如果传入的是一个联合类型,就会变成分发的 。相当于会自动一个个遍历进行判断


type StrArrOrNumArr = ToArray<string | number>;        
// type StrArrOrNumArr = string[] | number[]

了解了这些,我们就可以来实现Exclude了

因为T是联合类型,会自动遍历里面的属性, 当 T 中的属性存在于 U 时,就返回never ,否则返回遍历到的当前类型


type MyExclude<T, U> = T extends U ? never: T


Awaited



学习TypeScript28(infer 递归)_小满zs的博客-CSDN博客)


type MyAwaited<T> = T extends PromiseLike<infer K> ? MyAwaited<K> : T;

If



非常简单,不多解释


type If<C, T, F> = C  extends true ? T :F

Concat



直接用收集展开处理

type Concat<T, U> = [...T ,...U]

但是这时候却报错了,因为ts并不知道T,U是一个元组

image.png

用extends进行类型约束


type Concat<T extends any[], U extends any[]> = [...T ,...U]

Includes



思路很简单,依次遍历T里面有没有U这个属性,有的话就是true,否则返回false

来看代码怎么实现,先对比第一个,再递归对比剩余的


type Includes<T extends readonly any[], U> = T extends [infer one ,... infer rest]? 
one extends U ? true: Includes<rest,U>:
false

但是我们发现测试用例并没有全部通过

image.png我们在判断相等的时候,使用的extends。 但是false是 boolean的子集 ,返回的是true。但是我们想进行严格判断返回false,我们可以使用它提供的Equal函数(偷懒.png)


type Includes<T extends readonly any[], U> = T extends [infer one ,... infer rest]? 
Equal<one ,U> extends true ? true: Includes<rest,U>:
false

Push



同理


type Push<T extends any[], U> = [...T ,U]

Unshift




type Unshift<T  extends any[], U> = [U, ...T]

Parameters



把函数的参数收集起来,然后直接返回就好了


type MyParameters<T extends (...args: any[]) => any> = T extends (...rest:infer P) => any ? P : undefined



目录
相关文章
|
缓存 IDE 安全
基准测试神器JMH —— 详解36个官方例子
基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。而JMH是一个用来构建,运行,分析Java或其他运行在JVM之上的语言的 纳秒/微秒/毫秒/宏观 级别基准测试的工具。
2307 1
基准测试神器JMH —— 详解36个官方例子
|
消息中间件 运维 Java
【Log日志】logback.xml动态配置属性值(包括接入的第三方配置)
1如何动态配置Logback的存放路径 我们在开发过程中,会使用到logback.xml 配置来管理日志文件; 比如
|
10月前
|
关系型数据库 Go 网络安全
go语言中PostgreSQL驱动安装
【11月更文挑战第2天】
432 5
|
6月前
|
XML Java 数据库连接
优雅的参数校验,告别冗余if-else
本文介绍了在 Java Spring Boot 开发中如何使用 JSR 303 和 Hibernate Validator 进行参数校验,以避免冗余的if-else判断。文章涵盖了基本注解的使用、全局异常处理、分组校验、嵌套对象校验、快速失败配置以及自定义校验规则等实用技巧。
195 10
优雅的参数校验,告别冗余if-else
|
设计模式 Java Apache
Springboot项目优化日志logback-spring.xml详解
Commons Logging和Slf4j是日志门面(门面模式是软件工程中常用的一种软件设计模式,也被称为正面模式、外观模式。它为子系统中的一组接口提供一个统一的高层接 口,使 得子系统更容易使用)。log4j和Logback则是具体的日志实现方案。可以简单的理解为接口与接口的实现,调用这只需要关注接口而无需关注具体的实现,做到解耦
2481 0
Springboot项目优化日志logback-spring.xml详解
|
存储 负载均衡 应用服务中间件
LVS负载均衡群集——NAT模式实操
LVS负载均衡群集——NAT模式实操
1467 0
|
Web App开发 前端开发 JavaScript
如何判断HTML是否兼容
如何判断HTML是否兼容【2月更文挑战第11天】
205 5
|
算法 计算机视觉
【MATLAB】 ICEEMDAN信号分解+FFT傅里叶频谱变换组合算法
【MATLAB】 ICEEMDAN信号分解+FFT傅里叶频谱变换组合算法
1391 0
|
JavaScript
swiper插件实现echarts轮播的解决方案
swiper插件实现echarts轮播的解决方案
273 0