第六十一周总结——重拾ts类型体操
创始人
2024-05-31 23:26:59
0

重拾ts类型体操

匹配模式做提取

  1. 数组类型
  • 提取数组第一个元素的类型
type GetFirst = Arr extends [infer First, ...unknown[]] ? First : never;
  • 提取数组的最后一个元素的类型
type GetLast = Arr extends [...unknown[],infer Last] ? Last : never;
  • 去掉数组最后一个元素的类型
type PopArr = Arr extends [] ? [] : Arr extends [...infer Result,unknown] ? Result : never;
  • 去掉数组第一个元素的类型
type ShiftArr = Arr extends [] ? [] : Arr extends [unknown,...infer Result] ? Result : never;
  1. 字符串类型
  • 判断字符串是否以某个前缀开始
type StartWith = Str extends `${Start}${string}` ? true : false;
  • 字符串替换
type ReplaceStr = Str extends `${infer Prefix}${From}${infer Suffix}` ?ReplaceStr<`${Prefix}${To}${Suffix}`,From,To> : Str
  • 递归去除字符串中的右侧空格
type TrimStringRight = Str extends `${infer Result}${' '}` ? TrimStringRight : Str;
  • 递归去除字符串中的左侧空格
type TrimStringLeft = Str extends `${' '}${infer Result}` ? TrimStringLeft : Str;
  • 递归去除字符串中的左右侧空格
type TrimString = Str extends `${' '}${infer Result}${' '}` ? TrimString : Str;
  1. 函数
  • 提取参数的类型
type FunctionArgs = Fn extends (...args:infer Args) => unknown ? Args : never;
  • 提取返回值
type FunctionResult = Fn extends (...args:any[]) => infer Result ? Result : never;
  • 提取函数中的this
type FunctionThis = Fn extends (this:infer This,...args:unknown[])=>unknown ? This : never;
  1. 构造器
  • 匹配提取出实例对象
type GetInstanceTypeany> = Type extends new(...args:any) => infer Result ? Result : never;
// 测试案例
interface Person{name: string
}
interface PersonConstructor{new(name:string):Person
}
type person = GetInstanceType;
  • 提取构造器的参数
type GetInstanceParamany> = Type extends new(...args:infer Result) => unknown ? Result : never;
// 测试案例
interface Person{name: string
}
interface PersonConstructor{new(name:void):Person
}
type person = GetInstanceParam;
  1. 索引类型
  • 提取ref的值的类型
    ts类型体操,提取ref的值的类型。

重新构造做变换

  1. 数组类型的重新构造
  • 向数组后面添加元素
type Push = [...Arr,Ele];
  • 向数组前面添加元素
type Shift = [Ele,...Arr];
  • 合并只有两个元素的两个元组对应的元素
type Concat = 
One extends [infer OneFirst, infer OneSecond] ?Two extends [infer TwoFirst, infer TwoSecond] ? [[OneFirst,OneSecond],[TwoFirst,TwoSecond]] : []
: []
  • 合并只有任意个元素的两个元组对应的元素
type Concat = 
One extends [infer OneFirst,...infer OneOther] ?Two extends [infer TwoFirst,...infer TwoOther] ? [[OneFirst,TwoFirst],...Concat] : []
: [];
  1. 字符串的重新构造
  • 将字符串第一个元素转换成大写
type StringFistToUp = Str extends `${infer First}${infer Other}` ? `${Uppercase}${Other}` : never
  • 删除字符串中的某个字串
type DeleteString = 
Str extends `${infer Start}${Ele}${infer End}` ? DeleteString<`${Start}${End}`,Ele> : Str
  • 函数类型的重新构造
type FunAddParam =
Fn extends (...args:infer Args)=>infer Result ? (...args:[...Args,Arg])=>Result : never
  1. 索引类型重新构造
  • 把索引类型的Key变成大写
type KeyUp = {[Key in keyof Obj as Uppercase]:Obj[Key];
}
  • Record,typescript内置了Record,用来创建索引类型。
type _Record = {[P in K]: T
}
  • 将索引转换成只读
type ReadonlyParam = {readonly  [P in keyof T]: T[P]
}
  • 给索引添加可选修饰符
type toSelector = {[P in keyof T]?: T[P]
}
  • 去掉只读修饰符
type RemoveReadonly = {-readonly [P in keyof T]: T[P]
}
  • 去掉可选修饰符
type ClearSelector = {[P in keyof T]-?: T[P]
}
  • 对索引类型做过滤
type FilterValue,valueType extends unknown> = {[Key in keyof T as T[Key] extends valueType ? Key : never]: T[Key]
}

递归复用做循环

  1. Promise的递归调用
  • 提取不确定层数的Promise中的value类型的高级类型
type PromiseValue = 
T extends Promise?PromiseValue
: T
type promise = PromiseValue>>>
  1. 数组类型的递归
  • 不确定长度的元组反转
type ReverseArr> = T extends [infer First,...infer Other] ? [...ReverseArr,First] : T;
  • 寻找元组中是否存在某个元素
type IsEqual = (A extends B ? true : false) & (B extends A ? true : false);
type Include = 
Arr extends [infer First,...infer Other] ?IsEqual extends true ? true : Include
: false;
  • 删除元组中的某个元素
type RemoveArrItem = Arr extends [infer First,...infer Other] ?IsEqual extends true ? RemoveArrItem : RemoveArrItem
: Result
type IsEqual = (A extends B ? true : false) & (B extends A ? true : false)
  • 构建一个自定义长度的同一类别的数组
type BuildArr = Arr['length'] extends Length ? Arr : BuildArr
  1. 字符串类型的递归
  • 将字符串中的所用的指定字串替换成另一个字符串
type Replace = Str extends `${infer Start}${From}${infer End}` ? Replace<`${Start}${To}${End}`,From,To> : Str
  • 将字符串的每个元素提取出来转换成联合类型
type StrType = Str extends `${infer First}${infer Other}` ? StrType : Result
  • 反转字符串类型
type ReverseString = Str extends `${infer First}${infer Other}` ? ReverseStringResult}${First}`> : Result
  1. 对象类型的递归(索引类型的递归)

-递归将所有层的索引都变成只读
错误代码,如果测试一下我们就会发现,递归没有进行下去。因为ts的类型只有被用到的时候才会被计算。这里只是给第一次的索引加上了只读,但是没有使用。所以不会进行计算,我们可以加一个Obj extends any让其计算。

type DeepReadonly> = Obj extends any ? {readonly [Key in keyof Obj]: Obj[Key] extends Record ? Obj[Key] extends Function ? Obj[Key] : DeepReadonly: Obj[Key]
} : never

数组长度做计算

  1. 数组长度实现加减乘除
type BuildArray = Result['length'] extends Length ? Result : BuildArray
type Add = Arr extends [infer Start extends number,...infer Other]? Add,...Result]> : Result['length']
type s = Add<[1,2,3]>
type BuildArray = Result['length'] extends Length ? Result : BuildArray
type SubTract = BuildArray extends [...BuildArray,...infer Result] ? Result['length'] : never
type BuildArray = Result['length'] extends Length ? Result : BuildArray
type SubTract = BuildArray extends [...BuildArray,...infer Result] ? Result['length'] : nevertype Multiply = Num1 extends 0 ? Result['length'] : Multiply,Num2,[...Result,...BuildArray]>
type BuildArray = Arr['length'] extends Length ?Arr :BuildArray
type Subtract = BuildArray extends [...arr1: BuildArray, ...arr2: infer Rest] ?
Rest['length'] : nevertype Divide = Num1 extends 0 ?ResultArr['length'] :Divide,Num2,[unknown, ...ResultArr]>;
type divide = Divide<6,3>;
  • 求字符串的长度的类型
type StrLen = Str extends `${string}${infer Rest}`? StrLen
: ResultArr['length'];
type str = StrLen<'123'>;
  • 比较两个值的大小
type Than = Num1 extends Num2 ? false :Count['length'] extends Num2 ? true :Count['length'] extends Num1 ? false :Than
  • Fibonacci 数列的计算
type Fi = Idx['length'] extends Num ? Right['length'] : Fitype Fib = Fi<[],[1],Num,[1]>

联合分散可化简

  1. 将联合类型的字符串_去点,并将_后的第一个字母大写
type Tool = Str extends `${infer First}_${infer Start}${infer End}` ? Tool<`${First}${Uppercase}${End}`> : Str
type item = Tool<'aa_bb_cc_dd'>;
  1. 判断联合类型
type Tool =
A extends A?[B] extends [A] ? false : true
: never
  1. BEM
    BEM是css命名规范
type bemResult = BEM<'guang', ['aaa', 'bbb'], ['warning', 'success']>;
//会转换成
guang__aaa--warning guang__bbb--success
type BEM = `${Ele1}__${Ele2[number]}--${Ele3[number]}`
  1. AllCombinations
type Combination =| A| B| `${A}${B}`| `${B}${A}`;
type AllCombinations = 
A extends A? Combination>>: never;
type all = AllCombinations<'A' | 'B' | 'C'>;

特殊类型要记清

  1. IsEqual
type IsEqual = (()=>T extends A ? 1 : 2) extends (()=>T extends B ? 1 : 2) ? true : false
  1. 几个条件类型的特殊情况
  • 联合类型作为类型参数在条件类型左边的时候,会把每个类型单独传入做计算,并把结果合并成联合类型。
type Test = T extends number ? 1 : 2;
type res = Test<1 | 'a'>;//type res = 1 | 2
  • boolean也是联合类型,是false | true。
type Test = T extends true ? 1 : 2;
type res = Test;//type res = false | true
  • any类型如果在条件类型的左边,则返回trueType和falseType的联合类型。
type Test = T extends true ? 1 : 2;
type res = Test;//type res = 1 | 2
  • 当条件类型的左侧是never的时候直接返回never。
type Test = T extends true ? 1 : 2;
type res = Test;//type res = never

内置高级类型

  1. Parameters-用来提取函数参数的类型
type Parameters any> = T extends (...args: infer P) => any ? P : any;
  1. ResultType-用来提取函数的返回值类型
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
  1. ConstructorParameters-用来提取构造器的参数类型
type ConstructorParameters any> = T extends abstract new (...args: infer P) => any ? P : never;
  1. InstanceType-用来提取构造器的返回值类型
type InstanceType any> = T extends abstract new (...args: any) => infer R ? R : any;
  1. Partial-把索引类型变成可选类型
type Partial = {[P in keyof T]?: T[P];
};
  1. Required-把可选的索引类型变成必选类型
type Required = {[P in keyof T]-?: T[P];
};
  1. Readonly-把索引类型变成只读类型
type Readonly = {readonly [P in keyof T]: T[P];
};
  1. Pick-对索引进行修改和过滤,保留对应的索引
type Pick = {[P in K]: T[P];
};
  1. Record-用来创建索引类型
type Record = {[P in K]: T;
};
  1. Exclude-用来删除联合类型的一部分
type Exclude = T extends U ? never : T;
  1. Extract-用来保留联合类型的一部分
type Extract = T extends U ? T : never;
  1. Omit-和Pick相反,去掉对应的索引
type Omit = Pick>;
  1. Awaited-用来获取Promise的ValueType的类型
type Awaited =T extends null | undefined? T : T extends object & { then(onfulfilled: infer F): any }? F extends ((value: infer V, ...args: any) => any)? Awaited: never : T;
  1. NonNullable-用来判断是否为非空类型
type NonNullable = T extends null | undefined ? never : T;
  1. ThisParameterType-函数里可以调用 this,这个 this 的类型也可以约束。
type ThisParameterType = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
  1. OmitThisParameter-用来提取this
type OmitThisParameter = unknown extends ThisParameterType ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...