TypeScript 杂记四 《Sum》

Posted 左手121

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 杂记四 《Sum》相关的知识,希望对你有一定的参考价值。

TypeScript 杂记四 《Sum》

Sum

type T0 = Sum<2, 3> // '5'
type T1 = Sum<'13', '21'> // '34'
type T2 = Sum<'328', 7> // '335'
type T3 = Sum<1_000_000_000_000n, '123'> // '1000000000123'
  • 输入的类型为 number string 和 bigint,大致定义如下:
type Sum<A extends string | number | bigint, B extends string | number | bigint> = Helper<A, B>
  • 检验数据是否输入有误
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 Sum<
  A extends string | number | bigint,
  B extends string | number | bigint,
> = Check<A> extends true ? (Check<A> extends true ? Helper<A, B> : never) : never
  • 转化成字符串,并剔除字符串时候多余的 0
type ToString<T extends string | number | bigint> = T extends `0$infer L` ? ToString<L> : `$T`

type Sum<
  A extends string | number | bigint,
  B extends string | number | bigint,
> = Check<A> extends true
  ? Check<A> extends true
    ? Helper<ToString<A>, ToString<B>>
    : never
  : never
  • 实现单个数字的加
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 A = Plus<['1', '2'], ['9', '8']> // ["1", "1", "0"]
  • 将字符串转数组,将数组转字符串
type STA<T extends string, RR extends string[] = []> = T extends `$infer L$infer R`
  ? STA<R, [...RR, L]>
  : RR

type ATS<T extends unknown[]> = T extends [infer L, ...infer R]
  ? L extends string
    ? `$L$ATS<R>`
    : ''
  : ''
  • 完整
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 ToString<T extends string | number | bigint> = T extends `0$infer L` ? ToString<L> : `$T`

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

type ATS<T extends unknown[]> = T extends [infer L, ...infer R]
  ? L extends string
    ? `$L$ATS<R>`
    : ''
  : ''

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 Helper<A extends string, B extends string> = ATS<Plus<STA<A>, STA<B>>>

type Sum<
  A extends string | number | bigint,
  B extends string | number | bigint,
> = Check<A> extends true
  ? Check<B> extends true
    ? Helper<ToString<A>, ToString<B>>
    : never
  : never

type T0 = Sum<2, 3> // '5'
type T1 = Sum<'13', '21'> // '34'
type T2 = Sum<'328', 7> // '335'
type T3 = Sum<1_000_000_000_000n, '123'> // '1000000000123'

以上是关于TypeScript 杂记四 《Sum》的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 杂记十二 《Multiply》

TypeScript 杂记九 《Integers Comparator》

TypeScript 杂记九 《Integers Comparator》

TypeScript 杂记九 《Integers Comparator》

TypeScript 杂记一

TypeScript 杂记一