TypeScript 杂记十二 《Multiply》

TypeScript 杂记十二 《Multiply》

Multiply

type T0 = Multiply<2, 3>; // '6'
type T1 = Multiply<3, "5">; // '15'
type T2 = Multiply<"4", 10>; // '40'
type T3 = Multiply<0, 16>; // '0'
type T4 = Multiply<"13", "21">; // '273'
type T5 = Multiply<"43423", 321543n>; // '13962361689'

思路

  • 只考虑正整数,输入验证
type Check<T extends string | number | bigint> = T extends number | bigint
  ? true
  : T extends `${infer L}${infer R}`
  ? L extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
    ? Check<R>
    : false
  : true;
  • A * B 可以理解为 B 个 A 相加
    • 考虑到可能存在 bigint,因此我们把每一位的数字单独拎出来计算,然后加起来
    • 例如 100 * 123
    • 先算 100 * 1 结果为 R
    • 再算 100 * 2 + R0 结果为新的 R
    • 最后算 100 * 3 + R0 结果为新的 R
    • 上边的 R0 表示的是 R 后边多加一位 0
  • 两个数字相加,我们采用两个数组相加(计算每一位),参考之前的内容 《SUM》我们不对加法进行说明
type HelperOne<
  A extends string[],
  B extends string,
  H extends unknown[] = [],
  R extends string[] = ["0"]
> = `${H["length"]}` extends B
  ? R
  : HelperOne<A, B, [...H, unknown], Plus<A, R>>;

type Helper<
  A extends string[],
  B extends string,
  RR extends string[] = []
> = B extends `${infer L}${infer R}`
  ? Helper<A, R, Plus<[...RR, "0"], HelperOne<A, L>>>
  : RR;

结果

type Check<T extends string | number | bigint> = T extends number | bigint
  ? true
  : T extends `${infer L}${infer R}`
  ? L extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
    ? Check<R>
    : false
  : true;

type STA<
  T extends string,
  RR extends string[] = []
> = T extends `${infer L}${infer R}` ? STA<R, [...RR, L]> : RR;

type ATSHelper<T extends unknown[]> = T extends [infer L, ...infer R]
  ? L extends string
    ? `${L}${ATSHelper<R>}`
    : ""
  : "";

// '00010' 返回的是 '10'
// '000' 返回的是 '0'
type ATS<T extends unknown[]> = T extends ["0", ...infer R]
  ? ATS<R>
  : T extends []
  ? "0"
  : ATSHelper<T>;

type PlusOne<
  A extends string,
  B extends string,
  AA extends unknown[] = [],
  BA extends unknown[] = []
> = `${AA["length"]}` extends A
  ? `${BA["length"]}` extends B
    ? `${[...AA, ...BA]["length"] & number}`
    : PlusOne<A, B, AA, [...BA, unknown]>
  : PlusOne<A, B, [...AA, unknown], BA>;

type PlusHelper<A, B, F extends boolean = false> = PlusOne<
  A extends string ? A : "0",
  PlusOne<B extends string ? B : "0", F extends true ? "1" : "0">
> extends `${infer _1}${infer _2}`
  ? _2 extends ""
    ? [false, _1]
    : [true, _2]
  : [false, "0"];

type Plus<
  A extends unknown[] = [],
  B extends unknown[] = [],
  R extends string[] = [],
  F extends boolean = false
> = A extends [...infer LA, infer RA]
  ? B extends [...infer LB, infer RB]
    ? Plus<LA, LB, [PlusHelper<RA, RB, F>[1], ...R], PlusHelper<RA, RB, F>[0]>
    : F extends true
    ? Plus<
        LA,
        [],
        [PlusHelper<RA, "1", false>[1], ...R],
        PlusHelper<RA, "1", false>[0]
      >
    : [...A, ...R]
  : B extends [...infer LB, infer RB]
  ? F extends true
    ? Plus<
        [],
        LB,
        [PlusHelper<"1", RB, false>[1], ...R],
        PlusHelper<"1", RB, false>[0]
      >
    : [...B, ...R]
  : F extends true
  ? ["1", ...R]
  : R;

type HelperOne<
  A extends string[],
  B extends string,
  H extends unknown[] = [],
  R extends string[] = ["0"]
> = `${H["length"]}` extends B
  ? R
  : HelperOne<A, B, [...H, unknown], Plus<A, R>>;

type Helper<
  A extends string[],
  B extends string,
  RR extends string[] = []
> = B extends `${infer L}${infer R}`
  ? Helper<A, R, Plus<[...RR, "0"], HelperOne<A, L>>>
  : RR;

type Multiply<
  A extends string | number | bigint,
  B extends string | number | bigint
> = Check<A> extends true
  ? Check<B> extends true
    ? ATS<Helper<STA<`${A}`>, `${B}`>>
    : never
  : never;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值