TypeScript 杂记十二 《Multiply》
Posted 左手121
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 杂记十二 《Multiply》相关的知识,希望对你有一定的参考价值。
TypeScript 杂记十二 《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;
以上是关于TypeScript 杂记十二 《Multiply》的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript 杂记九 《Integers Comparator》
TypeScript 杂记九 《Integers Comparator》