TypeScript类型体操练习

历史小剧场

这个世界上,有两种人最痛苦,第一种是身居高位者,第二种是身居底层者,第一种人很少,第二种人很多。第一种人叫崇祯,第二种人叫百姓。
而最幸福的,就是中间那拨人,主要工作,叫做欺上瞒下,具体特点是,除了好事,什么都办;除了脸,什么都要。—《明朝那些事儿》

字符串模板与extends/infer

  • extends: 有两个作用:1、接口继承,2、类型判断(这篇文章主要是体现这个作用);
  • infer: 推导泛型参数,只在extends右边使用

案例

type str = "beyond";// 获开头
type getFirst<T> = T extends `${infer First}${infer Rest}`? First : never;
type FirstLetter = getFirst<str>; // type FirstLetter = "b"// 获取除开头的部分
type getRest<T> = T extends `${infer First}${infer Rest}` ? Rest : never;
type RestLetters = getRest<str>; // type RestLetters = "eyond"// 以y分隔
type Split<T> = T extends `${infer Front}y${infer Back}` ? Back : never;
type Splitted = Split<str>; // type Splitted = "ond"
判断开头
type startsWidth<str extends string, prefix extends string> = str extends `${prefix}${infer Rest}` ? true : false;
type startsWidthKong = startsWidth<"kong", "">; // type startsWidthKong = true
type StartsWithBe = startsWidth<str, "be">; //type StartsWithBe = true
type StartsWithC = startsWidth<str, "c">; // type StartsWithC = false
转为首字母大写
type UppercaseFirst<T extends string> = T extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : never;
type UppercaseStr = UppercaseFirst<str>; // type UppercaseStr = "Beyond"
文本替换-替换第一个
type ReplaceOne<str extends string, from extends string, to extends string> = str extends `${infer Front}${from}${infer Rest}` ? `${Front}${to}${Rest}` : str;
type ReplaceStr = ReplaceOne<str, "o", "a">; // type ReplaceStr = "beyand"
键值对转索引 a=1 => {a:1}
type ConvertStrToRecord<str extends string> = str extends `${infer key}=${infer value}` ? { [k in key]: value } : never;
type ConvertStrToRecordStr = ConvertStrToRecord<"a=1">; 
// type ConvertStrToIndexStr = {// a: "1";
// }

as 重映射-索引的重命名

索引转大写
interface IOut {aaa: 1,bbb: 2,fun: () => void
}
type UpperKeys<T extends Record<string, any>> = {[K in keyof T as (T[K] extends Function ? K : Uppercase<K>)]: T[K]
}
type res = UpperKeys<IOut>;
// type res = {
//     AAA: 1;
//     BBB: 2;
//     fun: () => void;
// }
合并索引
interface IOut2 {ccc: 3,ddd: 4
}
type CombineIndex<A extends Record<string, any>, B extends Record<string, any>> = {[K in keyof A | keyof B] : K extends keyof A ? A[K] : K extends keyof B ? B[K] : never
}
type combine = CombineIndex<IOut, IOut2>;
// type combine = {
//     aaa: 1;
//     bbb: 2;
//     fun: () => void;
//     ccc: 3;
//     ddd: 4;
// }

巧用递归

文本替换-替换所有
type ReplaceAll<Str extends string, From extends string, To extends string> = Str extends `${infer Front}${From}${infer Rest}` ? `${Front}${To}${ReplaceAll<Rest, From, To>}` : Str;
type ReplaceAllStr = ReplaceAll<"12333333456", "3", "A">; // type ReplaceAllStr = "12AAAAAA456"
字符串反转
type Reverse<Str extends string, Res extends string = ""> = Str extends `${infer First}${infer Rest}` ? Reverse<Rest, `${First}${Res}`> : Res;
type ReverseStr = Reverse<"hello">; // type ReverseStr = "olleh"

综合

字符串解析-初级

例如:我们要将 a=1&b=2&c=3 转为 {a:1, b:2, c:3}
那么,我们要有按这三步走

  1. &分割取 键值对 处理
  2. 处理单个的 键值对 转换为 索引类型
  3. 把 转换后的 索引类型 合并
type Parse<Str extends string, Res extends Record<string, any> = {}> = Str extends `${infer One}&${infer Rest}` ?Parse<Rest, CombineIndex<Res, ConvertStrToRecord<One>>> :CombineIndex<Res, ConvertStrToRecord<Str>>type parseToRecord = Parse<"a=1&b=2&c=3">; // type parseToRecord = {a: "1", b: "2", c: "3"}
字符串解析-升级
  • 如果只有键没有值,则返回 {key: true};
  • 合并重复索引。例如 a=1&a=2 转为 {a: [‘1’, ‘2’]};
  • 合并的值不能重复。例如 a=1&a=2&a=2 转为 {a: [‘1’, ‘2’]};
type ConvertStrToRecordUp<Str extends string> = Str extends `${infer Key}=${infer Value}` ? { [K in Key] : Value } : Str extends `${infer Key}` ? { [K in Key]: true } : {};
type ConvertStrToRecordUpStr = ConvertStrToRecordUp<"a">;
// type ConvertStrToRecordUpStr = {
//     a: true;
// }// 合并重复索引
type CheckDuplicate<A extends Record<string, any>, B extends Record<string, any>> = keyof B extends keyof A ? AddR<A, B> : CombineIndex<A, B>;
type AddR<A extends Record<string, any>, B extends Record<string, any>> = {[K in keyof A] : K extends keyof B ?CheckInclue<A[K], B[K]> extends true ? A[K] :  // 重复索引,合并值,值不能重复A[K] extends any[] ? [...A[K], B[K]] : [A[K], B[K]] : A[K]
}type CheckInclue<A extends any[], B extends string> = A extends [infer First, ...infer Rest] ? First extends B ? true : CheckInclue<Rest, B> : false;
type checkIncludeDemo = CheckInclue<["a", "b", "c"], "a">; // type checkIncludeDemo = truetype ParseUp<Str extends string, Res extends Record<string, any> = {}> = Str extends `${infer One}&${infer Rest}` ?ParseUp<Rest, CheckDuplicate<Res, ConvertStrToRecordUp<One>>> :CheckDuplicate<Res, ConvertStrToRecordUp<Str>>type parseToRecordUp = ParseUp<"a=1&b&a=2&a=3&c&d=4&e&e=10&a=3">; 
// type parseToRecordUp = {
//     b: true;
//     c: true;
//     a: ["1", "2", "3"];
//     e: [true, "10"];
//     d: "4";
// }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NOIP2013普及组复赛】题2:表达式求值

题2&#xff1a;表达式求值 【题目描述】 给定一个只包含加法和乘法的算术表达式&#xff0c;请你编程计算表达式的值。 【输入文件】 输入仅有一行&#xff0c;为需要你计算的表达式&#xff0c;表达式中只包含数字、加法运算符 “ ” “” “”和乘法运算符 “ ∗ ” “…

根据标签名递归读取xml字符串中element

工具类&#xff1a; /*** 根据标签名递归读取xml字符串中element* 例&#xff1a;* String xml * "<req>\n" * "<tag1></tag1>\n" * "<tag2>\n" * " <tag4></tag4>\n" * "</tag2>\n&…

go panic和recover

panic 能够改变程序的控制流&#xff0c;调用 panic 后会立刻停止执行当前函数的剩余代码&#xff0c;并在当前 goroutine 中递归执行调用方的 defer。recover 可以中止 panic 造成的程序崩溃。它是一个只能在 defer 中发挥作用的函数&#xff0c;在其他作用域中调用不会发挥作…

如何在线转换图片的格式?一键修改图片格式的方法

图片是日常生活和工作中的一种常用的内容展示类型&#xff0c;在使用图片的时候不同用途需要使用的图片格式也是不同的&#xff0c;比如我们手中有一张jpg格式图片&#xff0c;但是平台上传要求格式是png&#xff0c;那么怎样才能将jpg转png格式呢&#xff1f;下面将教大家图片…

模拟量4~20mA电流传感器接线方式

一、模拟量4~20mA电流传感器接线方式 无源双线制是常见的电流型传感器接线方式&#xff0c;它具有简单、经济的特点。其接线方式如下&#xff1a; 传感器的“”接到数据采集器的电源“”上&#xff0c; 传感器的“-”端子连接到数据采集器的“AI”端子上&#xff0c; 数据采集器…

无人机+EasyDSS互联网视频平台:构建秸秆焚烧监控的“天眼”系统

一、方案背景 在每年的夏收时节&#xff0c;秸秆禁烧成为各地政府面临的一项重要任务。随着夏收季节的结束&#xff0c;大量农作物秸秆的处理问题逐渐凸显。一方面农作物种植面积辽阔&#xff0c;禁烧区域面积较大&#xff0c;监管巡逻人员的数量有限&#xff0c;无法全面顾及…

使用 ASM 修改字段类型,解决闪退问题

问题 我的问题是什么&#xff1f; 在桥接类 UnityBridgeActivity 中处理不同 unity 版本调用 mUnityPlayer.destroy(); 闪退问题。 闪退日志如&#xff1a; 闪退日志说在 UnityBridgeActivity中找不到类型为 UnityPlayer 的属性 mUnityPlayer。 我们知道&#xff0c;Android…

【鸟叔的Linux私房菜】2-主机规划与磁盘分区

文章目录 2.1 Linux与硬件的搭配各硬件设备在Linux的文件名使用虚拟机学习 2.2 磁盘分区磁盘连接方式和设备文件名的关系MBR(MS-DOS)与GPT磁盘分区表MBR(MS-DOS)GPT磁盘分区表 启动流程的BIOS与UEFI启动检测程序BIOS搭配MBR/GPT的启动流程UEFI BIOS搭配 GPT启动的流程 Linux安装…

RGB 平均值统计

任务&#xff1a;有一一对应的图片多组如下&#xff0c;希望统计灰色部分原有grb平均值&#xff0c;彩色部分rgb平均值。 方法&#xff1a;由下图对各个像素分析&#xff0c;分为3类&#xff0c;并记录坐标&#xff0c;根据坐标统计上图的rgb平均值&#xff0c;结果放在一张Exc…

Linux完整版命令大全(十八)

quotacheck 功能说明&#xff1a;检查磁盘的使用空间与限制。语  法&#xff1a;quotacheck [-adgRuv][文件系统...]补充说明&#xff1a;执行quotacheck指令&#xff0c;扫描挂入系统的分区&#xff0c;并在各分区的文件系统根目录下产生quota.user和quota.group文件&#…

linux开发之设备树基本语法二

设备树特殊节点,对节点定义别名,chosen节点用来uboot给内核传参 上面的mmc0就是sdmmc0节点的别名 device_type属性 只对cpu节点和memory节点进行描述 自定义属性 这部分自定义,比如定义管脚标号,初始数值等 为什么我们可以在设备树上自己定义属性呢?设备树文件描述的是硬…

JD3-40/23漏电继电器 AC220V 50-500mA 0.1s 导轨安装

系列型号&#xff1a; JD3-40/13漏电继电器JD3-40/23漏电继电器JD3-40/33漏电继电器JD3-40/43漏电继电器 JD3-70/13漏电继电器JD3-70/23漏电继电器JD3-70/33漏电继电器JD3-70/43漏电继电器 JD3-100/23漏电继电器JD3-100/43漏电继电器JD3-100/33漏电继电器JD3-100/13漏电继电…

轻松入门Linux命令行(一)

1. 打开终端 在Linux系统中&#xff0c;我们可以通过终端&#xff08;Terminal&#xff09;来执行各种命令。不同的Linux发行版可能有不同的终端程序&#xff0c;但通常都可以在应用程序菜单中找到。打开终端后&#xff0c;我们就可以看到一个命令行提示符&#xff0c;等待我们…

260 基于matlab的工业乙醇发酵GUI仿真

基于matlab的工业乙醇发酵GUI仿真。首先对经典的流加半经验半理论模型进行动态和稳态仿真&#xff0c;考虑实际情况密&#xff0c;逐步将温度&#xff0c;气体排放等因素考虑到模型中去&#xff0c;进行综合性仿真。结合GUI技术&#xff0c;以动力学模型为核心&#xff0c;制作…

国产高边驱动对标英飞凌BTS7020-2

车规级高边驱动系列产品可P2P替换BTS7020-2的高边驱动芯片。类比半导体高边驱动产品可用于驱动车身控制域中的各种阻性、感性及容性负载的驱动&#xff0c;其在车内外的应用非常广泛&#xff0c;包括车内饰灯、头尾灯、座椅和方向盘及后视镜加热、电磁阀、门锁、电机等场景。 …

svg画简单的立方体

开发背景 要开发一个拖拽的大屏项目&#xff0c;其中涉及到一个装饰组件&#xff0c;是一个立方体cube&#xff0c;要求颜色可以修改&#xff0c;大小可以拖拽改变。 效果如下 分析 经过我一番奇思妙想&#xff0c;决定用svg实现&#xff0c;因为对svg比较熟悉。那就先来在草…

python前端通过API接口调用与后端进行数据交互前端如何调用api接口获取电商平台商品实时评论信息数据

要在Python前端通过API接口调用与后端进行数据交互并获取商品实时评论信息数据&#xff0c;可以通过封装好的api接口通过链接直接请求获取商品数据&#xff0c;以下是接入api的请求示例&#xff1a; # coding:utf-8 """ Compatible for python2.x and python3.…

柯桥成人职场英语/Excuse me 是 “不好意思”,那 Excuse you呢?

口语中&#xff0c;excuse me的使用频率非常高 甚至已经成为大家的口头禅 用在一些表示歉意或者打扰对方的场合 本来excuse me的用法就已经够丰富了 没想到竟然还有excuse you&#xff1f; 哈哈哈&#xff0c;别蒙圈 这篇就给大家捋捋excuse的那些表达 快和小编一起来学学…

【博客20】缤果Matlab串口调试助手V1.0(中级篇)

超级好用的Matlab串口调试助手 开发工具: MATLAB 2024a中文版 (编程语言matlab) 目录 前言 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 ​ ​---- ◇♣♡♠ ---- 2.其他扩展App展示 ​编辑 三、获取 >> 源码以及Git记录&#xff1a; 总结 前…

海外仓系统要多少钱?最贵的未必是最好的,性价比高的才是

海外仓系统可以说已经是现在海外仓管理不可或缺的重要工具&#xff0c;然而&#xff0c;很多海外仓企业在选择海外仓系统时最头疼的问题就是不知道到底多少钱才合适。 确实&#xff0c;现在的海外仓系统市场价格体系非常多&#xff0c;几万几十万各种定价都有&#xff0c;让人…