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'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值