我的编程空间,编程开发者的网络收藏夹
学习永远不晚

TypeScript类型实现加减乘除详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

TypeScript类型实现加减乘除详解

引言

在网上看到这道题目:请用TS类型实现整除?

type A = Divide<1, 0> // never
type B = Divide<4, 2> // 2
type C = Divide<10, 3> // 3

看完题目,我真的毫无思路,TS类型还能实现除法???一脸懵逼的我认真地研究了一位叫做  JoeYan大佬的解答:

type Tuple<T extends number, U extends any[] = []> =
    U['length'] extends T ? U : Tuple<T, [...U, any]>
type Subtract<
    A extends number,
    B extends number
> = Tuple<A> extends [...Tuple<B>, ...infer R] ? R['length'] : never
type SmallerThan<
    A extends number,
    B extends number,
    S extends any[] = []
> = S['length'] extends B
    ? false
    : S['length'] extends A
    ? true
    : SmallerThan<A, B, [...S,A]>
type Divide<A extends number, B extends number, S extends any[] = []> =
    B extends 0 ? never : SmallerThan<A, B> extends true ? S['length'] : Divide<Subtract<A, B>, B, [...S, any]>;
type res = Divide<200, 10> // 20

分析

乍一看,真的惊呆了,但是一步一步分析,还是能够看懂的,本文将整个研究的过程记录了下来:

TS类型没有直接提供数字的加减乘除,所以这位大佬的减法和整除都是通过数组长度计数来实现的。我平时体操练习很少,在没看他的解答前,我永远不会想到还能这么玩儿。

Divide

如果要实现98%10,假设A是98,B是10,让A一直减B,直到A小于B,无法继续再减,就能得到整除的结果。

A能减去9次B,每次进行减10的时候,往S(用来计数的数组,初始值为空数组)里面push一个元素。A减去9次10后,S数组的长度是9。此时A是8,B是10,A小于B,返回S的长度9。

type Divide<A extends number, B extends number, S extends number[] = []> =
    B extends 0 ? never : SmallerThan<A, B> extends true ? S['length'] : Divide<Subtract<A, B>, B, [...S, any]>;

上面这段代码的字面意思是:

  • B是否为0,直接返回never
  • A如果小于B,返回S的长度
  • A如果大于B,我们执行A-B,然后我们给S数组push一个元素,再次计算Divide

接下来,让我们开始逐个分析。

SmallerThan

SmallerThan用于判断A是否小于B

type res = SmallerThan<10,2>  // res为false
type res = SmallerThan<2,20> // res为true
type SmallerThan<
    A extends number,
    B extends number,
    S extends any[] = []
> = S['length'] extends B
    ? false
    : S['length'] extends A
    ? true
    : SmallerThan<A, B, [...S,any]>

字面上看起来是:

  • S的长度等于B,返回false
  • S的长度不等于B且S的长度等于A,返回true
  • S的长度不等于A和B,将any推入S数组

接下来举例来看:

type res = SmallerThan<3,2>  
// 首先S['length']=0 ,所以不等于A和B,此时将any推入数组,S数组变成[any]
// 接下来S['length'] =1,还是B等于A和B,此时继续将A放入数组,S数组变成[any,any]
// 此时S['length'] = 2,所以得出S的长度等于B,返回false

总之,S的长度是一次一次的累加的,先等于谁的长度,谁就更小。 如果S的长度先等于B的长度,那么就是A>B。如果S的长度先等于A的长度,就是A<B

Tuple

作用是将数字转成数组,且数组的长度等于数字的大小

type Tuple<T extends number, U extends any[] = []> =
    U['length'] extends T ? U : Tuple<T, [...U, any]>
type res4 = Tuple<3> // [any, any, any]‘
// 基本上和上面的SmallerThan差不多,就是不够长度,就push一个any进去

Subtract

顾名思义,获取A-B的值

type Subtract<
    A extends number,
    B extends number
> = Tuple<A> extends [...Tuple<B>, ...infer R] ? R : never
type res3 = Subtract<10,8> // [any, any]
type Subtract<
    A extends number,
    B extends number
> = Tuple<A> extends [...Tuple<B>, ...infer R] ? R['length'] : never
type res3 = Subtract<20,10> // 10
// 一开始把A转换长度为20的数组,B转换成长度为10的数组,然后让ts自己去infer,A的长度等于B的长度加上多少长度的数组,然后返回R的长度

最后

前面已经实现了整除和减法,本着练习的态度,让我们再实现一下乘法和加法。

加法

仿照前面的Subtract,不难实现:

type Add<A extends number, B extends number > = [...Tuple<A>,...Tuple<B>] extends [... infer T] ? T['length']:never

乘法

接下来,让我们实现一下乘法:

5*6 可以看作,5+5+5+5+5+5。

A*B,也就是A要累加自己B次。如果我们每进行一次加法,就让被乘数B减一,直到被乘数B为0,也就完成了累加。

type Tuple<T extends number, U extends any[] = []> =
    U['length'] extends T ? U : Tuple<T, [...U, any]>
type Mutiply<A extends number, B extends number, S extends any[] = []> = B extends 0 ? S['length'] : Mutiply<A, Subtract<B, 1>, [...S, ...Tuple<A>]>
type res = Mutiply<5,6> //30

坑点

type Tuple<T extends number, S extends any[] = []> = S['length'] extends T ? S : Tuple<T, [...S, any]> // 不报错
// type Tuple<T extends number, S extends any[] = []> = T extends S['length'] ? S : Tuple<T, [...S, any]> 
// 不能写成T extends S['length'],ts会报递归可能是无限的

总结

我觉得还是套路为主,在研究了别人的除法实现后,也就能很容易实现加法和乘法。但如果没有前面的研究,想破脑子也很难实现。

以上就是TypeScript类型实现加减乘除详解的详细内容,更多关于TypeScript类型加减乘除的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

TypeScript类型实现加减乘除详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

TypeScript类型实现加减乘除详解

这篇文章主要为大家介绍了TypeScript类型实现加减乘除示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-16

TypeScript类型怎么实现加减乘除

这篇文章主要讲解了“TypeScript类型怎么实现加减乘除”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“TypeScript类型怎么实现加减乘除”吧!在网上看到这道题目:请用TS类型实现整
2023-07-06

TypeScript类型实现加减乘除的方法是什么

这篇文章主要介绍了TypeScript类型实现加减乘除的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇TypeScript类型实现加减乘除的方法是什么文章都会有所收获,下面我们一起来看看吧。引言在网上
2023-07-06

Linux 中(加、减、乘、除)实例详解

Linux 中(加、减、乘、除)实例详解实现代码:#!/bin/bashnum1=10 num2=2#两个数相加 add=$[$num1+$num2] echo $num1 + $num2 '=' $add#两个数相减 sub=$[$num
2022-06-04

Java使用位运算实现加减乘除详解

这篇文章主要为大家详细介绍了Java如何使用位运算实现加减乘除,文中的示例代码讲解详细,对我们深入了解Java有一定的帮助,感兴趣的可以了解一下
2023-05-19

css中怎么实现加减乘除

这篇“css中怎么实现加减乘除”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“css中怎么实现加减乘除”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让我们进入主题吧。
2023-06-06

javascript实现加减乘除的方法

这篇文章将为大家详细讲解有关javascript实现加减乘除的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。javascript实现加减乘除的方法:首先使用“document.getElementBy
2023-06-14

php函数如何实现加减乘除

这篇文章主要介绍“php函数如何实现加减乘除”,在日常操作中,相信很多人在php函数如何实现加减乘除问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php函数如何实现加减乘除”的疑惑有所帮助!接下来,请跟着小编
2023-07-04

php怎么实现加减乘除的运算

php实现加减乘除运算的方法:1、创建一个php示例文件;2、定义两个变量为“$x”和“$y”;3、通过“$x+$y”,“$x-$y”,“$x*$y”及“$x/$y”公式实现加减乘除运算;4、使用“echo”输出运算结果即可。
2023-05-14

怎么用PHP类来实现两个数间的加减乘除

本篇内容主要讲解“怎么用PHP类来实现两个数间的加减乘除”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用PHP类来实现两个数间的加减乘除”吧!首先打开PHP编辑器,创建一个PHP示例文件;上
2023-06-20

怎么用PHP实现简单的加减乘除

这篇文章主要讲解了“怎么用PHP实现简单的加减乘除”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用PHP实现简单的加减乘除”吧!本文的重点就是如何创建一个PHP类来实现两个数间的加减乘除
2023-06-20

编程热搜

目录