这应该是TypeScript类型体操专栏目前最复杂的工具类型了😱

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

好文推荐

前言

前边几篇文章我们一共实现了40 个工具类型,按照本专栏的规划,还差59个...

本节我们继续学习一个新的工具类型

提示

对于语法层面的知识点本系列(类型体操开头的标题)不会展开说明哈,可以自行搜索学习其他大佬的优质文章或者等我后续更新补充

实现

这个工具类型实现的关键点是如何模拟乘法运算,显然这可以通过数组来实现

比如2的平方是4,可以使用数据长度来表示,即[1,2,1,4],至于数组中的元素具体是什么,并不需要关心

了解了这一点,就很好定义其入参了。如下,T表示一个数字,U是平方数对应长度的数组

ts 复制代码
type Square<
    T extends number,
    U extends any[]=[]
  >

而它的结果必然是对U的长度的取值

ts 复制代码
U['length']

现在问题变成了U如何基于T计算特定的长度,如下定义GetSquareLength来完成

ts 复制代码
type GetSquareLength<
    T extends number,
    U extends any[]=[]
  >

由于数组长度与数值T之间的关系是T✖️T,而能构造的条件只与长度相关

ts 复制代码
U['length'] extends T

故,还需要第三个参数R来进行补位

ts 复制代码
type GetSquareLength<
    T extends number,
    U extends any[]=[],
    R extends any[]=[]
  >

至于R的计算,可以通过列举来找规律

ts 复制代码
/**
 * U R
 * 1 0
 * 2 2
 * 3 6
 * 4 12
 * 5 20
 * 6 30
 * 7 42
 * 8 56
 */

可以看出,上一次的U的两倍+上一次的R的值,刚好就是本次的R

ts 复制代码
/**
* U   U   R   
* 1 + 1 + 0 = 2
* 2 + 2 + 2 = 6
* 3 + 3 + 6 = 12
* 4 + 4 + 12 = 20
* 5 + 5 + 20 = 30
* 6 + 6 + 30 = 42
* 7 + 7 + 42 = 56
*/

故GetSquareLength的完整实现如下

ts 复制代码
type GetSquareLength<
    T extends number,
    U extends any[]=[],
    R extends any[]=[]
  > = 
  U['length'] extends T 
  ? [...U,...R] 
  : GetSquareLength<T,[1,...U],[...U,...U,...R]>

当为正数时这似乎是没什么问题

当为负数时,就会出现无限递归的情况了

所以,还有对T其取绝对值

ts 复制代码
type Abs<
    N extends number
  > = 
  `${N}` extends `-${infer R extends number}` 
  ? R 
  : N;

如上,当N为2时,2-2的结果是N,即2;当N为-2时,-2-2的结果是R,即2

故,完整的GetSquareLength如下

此时,再传递负数就不会再报错了

则我们得到了如下的Square类型

ts 复制代码
type Square<
    T extends number,
    U extends any[] = GetSquareLengthArr<T>
  > = U['length']

这似乎已经大功告成了

4也好

78也好

都表现的还不错😌

故完整代码如下

思考

当尝试输入一个较大的数值时,得到了如下的提示。这说明我们的计算本身是没问题的,只是生成的数组太大

那有办法解决吗?

路 笔者有思路如下......

找到一个临界值,假设是100,以118为例子,可拆分为

ts 复制代码
(100 + 18) * (100 + 18)

他们的结果为各项乘积的和

ts 复制代码
100 * 100  + 100 * 18 + 18 * 100 + 18 * 18

则现在的问题有两个:

  • 如何拆分?

  • 如何相加?

思考一下,评论区讨论,或者关注我,后续揭晓哦🌹

下期预告

GetMiddleElement

  • 功能

获取数组的中间元素

  • 使用示例
ts 复制代码
type case = GetMiddleElement<[1,2,3,4,5]> // 3

如果本文对您有用,希望能得到您的点赞和收藏

订阅专栏 ,每更新1-2篇类型体操,等你哟😎

相关推荐
MiyueFE18 小时前
🚀🚀五个前端开发者都应该了解的TS技巧
前端·typescript
ttod_qzstudio19 小时前
基于typescript严格模式以实现undo和redo功能为目标的命令模式代码参考
typescript·命令模式
张志鹏PHP全栈20 小时前
TypeScript 第十天,TypeScript面向对象之Class(二)
前端·typescript
慧一居士21 小时前
ESLint 完整功能介绍和完整使用示例演示
前端·javascript·typescript
enzeberg2 天前
TypeScript 工具类型(Utility Types)
typescript
難釋懷2 天前
TypeScript类
前端·typescript
杰哥焯逊2 天前
基于TS封装的高德地图JS APi2.0实用工具(包含插件类型,基础类型)...持续更新
前端·javascript·typescript
工业甲酰苯胺3 天前
TypeScript枚举类型应用:前后端状态码映射的最简方案
javascript·typescript·状态模式
土豆骑士4 天前
简单理解Typescript 装饰器
前端·typescript
ttod_qzstudio4 天前
彻底移除 HTML 元素:element.remove() 的本质与最佳实践
前端·javascript·typescript·html