Skip to content

数组长度做计数

前言

TypeScript 类型系统中没有加减乘除运算符,但是可以通过构造不同的数组然后取 length 的方式来完成数值计算,把数值的加减乘除转化为对数组的提取和构造

typescript
type num3 = [unknown, unknown, unknown]['length'] // 3

加减乘除

实现一个构造不确定长度数组的类型

typescript
type BuildArray<Len extends number, Result extends unknown[] = []> = 
    Result['length'] extends Len
        ? Result
        : BuildArray<Len, [...Result, unknown]>s

typescript
type Add<Num1 extends number, Num2 extends number> = 
    [...BuildArray<Num1>,...BuildArray<Num2>]['length']

type Result = Add<32, 25> // 57

typescript
type Subtract<Num1 extends number, Num2 extends number> = 
    BuildArray<Num1> extends [...arr1: BuildArray<Num2>, ...arr2: infer R]
        ? R['length']
        : never

type Result = Subtract<32, 25> // 7

乘法就是多个加法结果的累加

typescript
type Mutiply<Num1 extends number, Num2 extends number, R extends unknown[] = []> = 
    Num2 extends 0
        ? R['length']
        : Mutiply<Num1, Subtract<Num2, 1>, [...R, ...BuildArray<Num1>]>

type MutiplyResult = Mutiply<1, 5> // 5

除法就是递归的累减

typescript
type Divide<
    Num1 extends number,
    Num2 extends number,
    CountArr extends unknown[] = []
> = Num1 extends 0 ? CountArr['length']
        : Divide<Subtract<Num1, Num2>, Num2, [unknown, ...CountArr]>

type Result = Divide<9, 3>

比较

往一个数组类型中不断放入元素取长度,如果先到了 A,那就是 B 大,否则是 A 大

typescript
type GreaterThan<
    Num1 extends number,
    Num2 extends number,
    CountArr extends unknown[] = []
> = Num1 extends Num2
        ? false
        : CountArr['length'] extends Num2
            ? true
            : CountArr['length'] extends Num1
                ? false
                : GreaterThan<Num1, Num2, [unknown, ...CountArr]>

type Result = Divide<4, 3> // true