TypeScript 杂记四 《Sum》
Sum
type T0 = Sum<2, 3>
type T1 = Sum<'13', '21'>
type T2 = Sum<'328', 7>
type T3 = Sum<1_000_000_000_000n, '123'>
- 输入的类型为 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
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']>
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>
type T1 = Sum<'13', '21'>
type T2 = Sum<'328', 7>
type T3 = Sum<1_000_000_000_000n, '123'>