Easy

1. Easy - 4 - Pick

从类型 T 中选出符合 K 的属性,构造一个新的类型

type MyPick<T, K extends keyof T> = {
[key in K]: T[key]
}
  • keyof 是 TypeScript 中的一个关键字,用于获取一个类型的所有属性名组成的联合类型。
  • extends 可以用于约束泛型类型参数、定义类型继承关系和条件类型的判断。
  • 在映射类型中,可以通过 in 关键字遍历联合类型,可以用于遍历一个类型的属性名(需要通过 keyof 获取属性名组成的联合类型),并对每个属性进行相应的操作。

2. Easy - 7 - Readonly

泛型 Readonly<T> 会接收一个泛型参数,并返回一个完全一样的类型,只是所有属性都会是只读 (readonly) 的。

type MyReadonly<T> = {
readonly [key in keyof T]: T[key];
}
  • 在 TypeScript 中,可以使用 readonly 修饰符来指定一个只读属性。

3. Easy - 11 - Tuple to Object

将一个元组类型转换为对象类型,这个对象类型的键/值和元组中的元素对应。

type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[key in T[number]]: key
}
  • 元组类型是 TypeScript 中的一种特殊数据类型,它允许我们定义一个固定长度和固定类型顺序的数组。
  • 通过 T[number] 可以获取元组 T 所有成员组成的联合类型。
  • 加readonly 的作用,因为测试用例定义的变量都是 constconst的作如下:
const tupleNumber = [1, 2, '33'] // (string | number)[]
const tupleNumber = [1, 2, '33'] as const // readonly [1, 2, "33"]

4. Easy - 14 - First of Array

实现一个 First<T> 泛型,它接受一个数组 T 并返回它的第一个元素的类型。

// 解法一:判断数组长度是否为0
type First<T extends any[]> = T['length'] extends 0 ? never : T[0]
// 解法二:判断是否为空数组
type First<T extends any[]> = T extends [] ? never : T[0]
// 解法三:获取T所有元素类型组成的联合类型,如果为never证明为空数组
type First<T extends any[]> = T[number] extends never ? never : T[0];
// 解法四:我们可以通过 keyof T 来获取类型 T 所有键的类型组合,那么如果 '0' 是 T 的键就表示 T 是一个非空数组
type First<T extends any[]> = '0' extends keyof T ? T[0] : never;
// 解法五:infer进行模式匹配
type First<T extends any[]> = T extends [infer A, ...infer _rest] ? A : never
  • 在 TS 中 A extends B ? C : D 的意思是“如果 A 可以赋值给 B,那么类型就是 C,否则就是 D”。
  • T[0] 获取数组 T 下标为 0 的元素类型
  • 在 TS 中,我们通过 extends 和 infer 可以实现一个类似于模式匹配的效果,
  • 其中 ...infer _rest 是我们对元组类型使用的扩展运算,在这里用于表示剩余元素。

5. Easy - 18 - Length of Tuple

创建一个Length泛型,这个泛型接受一个只读的元组,返回这个元组的长度。

type Length<T extends readonly unknown[]> = T['length']
  • 注意必须是 const 的类型,否则长度类型为 number

6. Easy - 43 - Exclude

从联合类型 T 中排除 U 中的类型,来构造一个新的类型。

type MyExclude<T, U> = T extends U ? never : T;
  • T extends U ? ... 中的 T 为联合类型时,会把联合类型中的每一个类型单独进行判断,然后再把结果组合成一个联合类型返回。
  • 如果你想避免这种行为,那么使用 [] 包裹你的类型参数即可,注意在 extends 关键字的两侧都需要: [T] extends [U] ? ...

7. Easy - 189 - Awaited

假如我们有一个 Promise 对象,这个 Promise 对象会返回一个类型。在 TS 中,我们用 Promise 中的 T 来描述这个 Promise 返回的类型。请你实现一个类型,可以获取这个类型。

interface Thenable<T> {
then: (onfulfilled: (arg: T) => any) => any
} type MyAwaited<T extends Promise<any> | Thenable<any>> = T extends Promise<infer A> | Thenable<infer A>
? A extends Promise<infer _X> ? MyAwaited<A> : A
: never

8. Easy - 268 - IF

实现一个 IF 类型,它接收一个条件类型 C ,一个判断为真时的返回类型 T ,以及一个判断为假时的返回类型 F。 C 只能是 true 或者 false, T 和 F 可以是任意类型。

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

9. Easy - 533 - Concat

在类型系统里实现 JavaScript 内置的 Array.concat 方法,这个类型接受两个参数,返回的新数组类型应该按照输入参数从左到右的顺序合并为一个新的数组。

type Concat<T extends any[], U extends any[]> = [...T, ...U]
  • 在 TS 中,扩展语法可以对元组类型使用,用法类似于在 JS 中对值的使用

10. Easy - 898 - Includes ※

在类型系统里实现 JavaScript 的 Array.includes 方法,这个类型接受两个参数,返回的类型要么是 true 要么是 false

type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2
? true
: false;
type Includes<T extends readonly unknown[], U> =
T extends [infer F, ...infer Rest]
? Equal<F, U> extends true ? true : Includes<Rest, U>
: false;
  • Equal 实现原理很复杂,暂时搞不懂,记住得了

11. Easy - 3057 - Push

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

12. Easy - 3060 - Unshift

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

13. Easy - 3312 - Parameters

实现内置的 Parameters 类型

type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
  • 使用 infer 表示待推断的类型变量,由于 ...args 本身已经是元组类型,因此 infer P 最终推导出的,也是元组类型。

Medium

1. Medium - 2 - Get Return Type

type MyReturnType<T> = T extends (...args: any) => infer R ? R : never

2. Medium - 3 - Omit *

解法一,去遍历 T 中除了 K 的键。

type MyExclude<T, P> = T extends P ? never : T;
type MyOmit<T, K extends keyof T> = {
[P in MyExclude<keyof T, K>]: T[key]
}

解法二,利用 Pick 实现,获取 T 中除了 K 的键

type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

解法三,直接实现

这样不对,因为不应该存在的键也会存在,只不过类型为never。

type MyOmit<T, K extends keyof T> = {
[P in keyof T]: P extends K ? never : T[key]
}

要将对应的键设置为never

type MyOmit<T, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P];
};

3. Medium - 3 - Readonly 2

MyReadonly2<T, K>TK 包含的属性置为 readonly 其余不变,不传 K 就把所有的属性变成 readonly,此时同 Readonly

重点是 K 可以不传,所以要赋默认值。

type MyReadonly2<T, K extends keyof T = keyof T> = Readonly<Pick<T, K>> & Omit<T, K>

TS体操类型学习记录的更多相关文章

  1. ElasticSearch 学习记录之Text keyword 两种基本类型区别

    ElasticSearch 系列文章 1 ES 入门之一 安装ElasticSearcha 2 ES 记录之如何创建一个索引映射 3 ElasticSearch 学习记录之Text keyword 两 ...

  2. (原)关于MEPG-2中的TS流数据格式学习

    关于MEPG-2中的TS流数据格式学习 Author:lihaiping1603 原创:http://www.cnblogs.com/lihaiping/p/8572997.html 本文主要记录了, ...

  3. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  4. Java 静态内部类与非静态内部类 学习记录.

    目的 为什么会有这篇文章呢,是因为我在学习各种框架的时候发现很多框架都用到了这些内部类的小技巧,虽然我平时写代码的时候基本不用,但是看别人代码的话至少要了解基本知识吧,另外到底内部类应该应用在哪些场合 ...

  5. UWP学习记录12-应用到应用的通信

    UWP学习记录12-应用到应用的通信 1.应用间通信 “共享”合约是用户可以在应用之间快速交换数据的一种方式. 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参 ...

  6. UWP学习记录11-设计和UI

    UWP学习记录11-设计和UI 1.输入和设备 通用 Windows 平台 (UWP) 中的用户交互组合了输入和输出源(例如鼠标.键盘.笔.触摸.触摸板.语音.Cortana.控制器.手势.注视等)以 ...

  7. UWP学习记录8-设计和UI之控件和模式5

    UWP学习记录8-设计和UI之控件和模式5 1.日历.日期和时间控件 日期和时间控件提供了标准的本地化方法,可供用户在应用中查看并设置日期和时间值. 有四个日期和时间控件可供选择,选择的依据如下: 日 ...

  8. UWP学习记录7-设计和UI之控件和模式4

    UWP学习记录7-设计和UI之控件和模式4 1.翻转视图 使用翻转视图浏览集合中的图像或其他项目(例如相册中的照片或产品详细信息页中的项目),一次显示一个项目. 对于触摸设备,轻扫某个项将在整个集合中 ...

  9. UWP学习记录6-设计和UI之控件和模式3

    UWP学习记录6-设计和UI之控件和模式3 1.按钮 按钮,响应用户输入和引发 Click 事件的控件. 使用<Button>就能创建一个按钮控件了.按钮是 ContentControl, ...

  10. UWP学习记录2-设计和UI之布局

    UWP学习记录2-设计和UI之布局 1.导航基础知识 应用里,多个页面会有层次关系或者对等关系.这两种关系,通常在一个复杂应用里都会存在,而关系的选定依据: 对于对等导航,一般用选项卡(tabs)或者 ...

随机推荐

  1. Android低功耗子系统的投票机制以及触发进入系统休眠的过程

    从kernel角度看,系统是否进入休眠应该由内核来控制,因此Linux引入了 wakeup source以及autosleep机制 关于wakeup source的介绍,请参考: Wakeup Sou ...

  2. hbuilderx打正式包所需的私钥证书的创建方法

    现在使用uniapp作为底层框架来开发app应用已经成为了很多公司的事实标准,而uniapp的开发工具hbuilderx云打包的时候,需要私钥证书和证书profile文件. 而且还需要将打包好的ipa ...

  3. windows edge浏览器免费复制网页文字

    复制时,出现上面提示时候 使用edge浏览器打开链接,在http前面加入read: ,然后打开,即可复制 如果用js,可以参考https://www.cnblogs.com/rmticocean/p/ ...

  4. 关于Isaac Gym的两个版本比较:IsaacGymEnvs/omni.isaac.gym

    原文地址: https://zhuanlan.zhihu.com/p/590468555 重点: IsaacGymEnvs (IGE)和 omni.isaac.gym (OIG)是两个东西. 原文内容 ...

  5. 《Python数据可视化之matplotlib实践》 源码 第一篇 入门 第三章

    图3.1 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np mpl.rcParams['font. ...

  6. 在单机条件下,MPI4PY与纯Python多进程代码来比较是否有性能优势???

    如题: 最近在看MPI4PY的代码,但是发现这东西除了编写简洁外(少量代码实现复杂的多进程通信,包括单机和多机),好像也没有别的太多功能,当然MPI本身在多机通信广播.规约上做的很成熟,但是假设我们只 ...

  7. [POI2015] POD 题解

    前言 题目链接:洛谷. 题意简述 长度为 \(n\) 的一串项链,每颗珠子是 \(k\) 种颜色之一.第 \(i\) 颗与第 \(i-1, i+1\) 颗珠子相邻,第 \(n\) 颗与第 \(1\) ...

  8. condition字符串匹配问题

    概述 freeswitch是一款简单好用的VOIP开源软交换平台. fs使用dialplan配置文件执行业务流程,condition条件变量的配置是必然会使用的,这里记录一次配置过程中的错误示范. 环 ...

  9. LemurBrowser狐猴浏览器:支持插件扩展、内置免费AI工具的移动端浏览器

    如何选择一款合适的浏览器? 在这个数字化时代,浏览器作为互联网的入口.然而,选择一款合适的浏览器却并不容易. 注释:狐猴浏览器是浏览器新标签页插件Wetab提供的支持在移动端安装插件,内置免费AI工具 ...

  10. Unreal使用GooglePAD生成AAB包,并加在fast-follow资源

    1.修改obbfilter,设置需要添加到obb的pak文件 2.修改项目设置,打AAB包 3.cook stage生成所有Paks文件 4.将部分pak文件拷贝到Intermediate/Andro ...