使用typescript类型系统实现正整数加法运算
本期将单纯使用工具类型实现,无任何js代码(除了展示类型的除外)代码量巨大,我就不搞解析了,完全基于本人对ts的理解写出来的原创代码,无任何借鉴,你说史山那就是史山
type number_string = ['0','1','2','3','4','5','6','7','8','9']
type number_ =
type big =
//移除元组开头元素
export type removeTop<A> = A extends ? [...data] : never
//结构对比
export type isOneType<t,T> = keyof t extends keyof T ? keyof T extends keyof t ? true : false : false
//全同对比
export type isOne<ty,yt> = ty extends yt ? yt extends ty ? true : false : false
//移除字符串开头的字符
type string_remove_top<s> = s extends `${infer _h}${infer data}` ? data : never
//获取字符串开头的字符
type get_string_top<s> = s extends `${infer _h}${infer ho}` ? _h :never
//字符串转数组
type string_to_array<s extends string,new_ extends []> = true extends isOne<s,''> ? new_ : string_to_array<string_remove_top<s>,[...new_,get_string_top<s>]>
export type StringToArray<s extends string> = string_to_array<s,[]>
//类型映射
export type type_to_else<t,contrast extends any[],to extends any[]> = true extends isOneType<t,contrast> ? to : type_to_else<t,removeTop<contrast>,removeTop<to>>
//获取元素索引
type indexof<target extends any[],type_ extends any,Counter extends []> = true extends isOne<target,type_> ? Counter['length'] : indexof<removeTop<target>,type_,>
export type indexOf<target,type_> = indexof<target,type_,[]>
//填充数组
export type fill_array<array extends any[],length extends number,element extends any[]> = true extends isOne<array['length'],length> ? array : fill_array<,length,element>
//分割数组
type partition<array extends any[],length extends number,result extends [[],[...array]]> = true extends isOne<result['length'],length> ? result : partition<removeTop<array>,length,[[...result,array],[...removeTop<array>]]>
export type Partition<array extends any[],length extends number> = partition<array,length,[[],[...array]]>
//简单加法
type ad<a extends number,b extends number> = [...fill_array<[],a,0>,...fill_array<[],b,0>]['length']
//给字符串开头添加字符串
type string_add_top<s extends string,a extends string> = `${a}${s}`
//字符串转数字(9以内)
type string_to_number<s extends string> = indexOf<number_string,s>
//个位
type individual_position<n extends number> = indexOf<big,n>
//移除数组末尾
type array_remove_end<n extends any[]> = n extends [...infer h,infer e] ? h : []
//获取数组末尾
type get_array_end<n extends any[]> =n extends [...infer h,infer e] ? e : n
//判断元素在不在数组
type includes<array extends any[],element extends any> = true extends isOne<array,[]> ? false : true extends isOne<get_array_end<array>,element> ? true : includes<array_remove_end<array>,element>
//进位
type carry<n extends number[],after extends number[],> = true extends isOne<n,[]> ? after : true extends isOne<n['length'],1> ? ,...after] : true extends includes<big,get_array_end<n>> ? carry<[...array_remove_end<array_remove_end<n>>,ad<get_array_end<array_remove_end<n>>,1>],> : carry<array_remove_end<n>,>
type Carry<n extends number[]> = carry<n,[]>
//拆解数字字符串
type partition_string<s extends string,new_ extends []> = true extends isOne<s,''> ? new_ : partition_string<string_remove_top<s>,[...new_,string_to_number<get_string_top<s>>]>
type PartitionString<s extends string> = partition_string<s,[]>
//默认值
type default_value<n,de> = true extends isOne<n,never> ? de : true extends isOne<n,undefined> ? de : true extends isOne<n,[]> ? de : n
//数组相加-末起
type array_number_add<a extends number[],b extends number[],c extends []> = true extends isOne<a,undefined> ? true extends isOne<b,undefined> ? c : array_number_add<array_remove_end<a>,array_remove_end<b>,> :array_number_add<array_remove_end<a>,array_remove_end<b>,>
type ArrayNumberAdd< a extends number[],b extends number[]> = array_number_add<a,b,[]>
//数字字符串数组转数字数组
type string_number_array_to_number_array<a extends string,result extends []> = true extends isOne<a,''> ? result : string_number_array_to_number_array<string_remove_top<a>,[...result,string_to_number<get_string_top<a>>]>
type StringArrayToNumberArray<a extends string> = string_number_array_to_number_array<a,[]>
display<string_number_array_to_number_array<'2738',[]>>()
//数组转字符串
type array_to_string<array extends any[],s extends string> = true extends isOne<array,[]> ? s : array_to_string<removeTop<array>,`${s}${array}`>
type add<a extends string,b extends string> = array_to_string<Carry<ArrayNumberAdd<StringArrayToNumberArray<a>,StringArrayToNumberArray<b>>>,''>
使用
function display<T>():T
你的ts基本功是我一辈子无法比拟的 ts体操一般难度,基本就是const数组特性[贴吧_滑稽]
type MetaNum = ['9', '8', '7', '6', '5', '4', '3', '2', '1', '0']
// 分割
type Split<
T extends string,
R extends boolean = false,
_R extends Array<string> = [],
> = T extends `${infer X}${infer Y}` ? (R extends true ? Split<Y, R, > : Split<Y, R, [..._R, X]>) : _R
// 联合
type Join<T extends Array<string>, R extends boolean = false, _R extends string = ''> = T extends [
infer A extends string,
...infer B extends Array<string>,
]
? Join<B, R, R extends true ? `${A}${_R}` : `${_R}${A}`>
: _R
// 获取索引
type ResolveIdx<T extends string, R extends Array<string> = MetaNum> = R extends
? T extends X
? R extends
? Rest['length']
: never
: ResolveIdx<T, Extract<Y, Array<string>>>
: never
// 创建空白索引数组
type GenBlankArr<T extends number, R extends Array<number> = []> = R['length'] extends T
? R
: GenBlankArr<T, [...R, R['length']]>
// 原子加发
type MetaAdd<A extends string, B extends string> = Extract<
[...GenBlankArr<ResolveIdx<A>>, ...GenBlankArr<ResolveIdx<B>>]['length'],
number
>
// 获取进位和余位
type ResolveNum<T extends number> = `${T}` extends `${infer X}${infer Y}` ? (Y extends '' ? ['0', X] : ) : never
// 递推进位值计算
type ReduceNum<
A extends string,
B extends string,
R extends Array<number> = [],
SplitA = Split<A, true>,
SplitB = Split<B, true>,
> = SplitA extends
? SplitB extends
? ReduceNum<Join<YA, true>, Join<YB, true>, [...R, MetaAdd<XA, XB>]>
: ReduceNum<Join<YA, true>, '', [...R, MetaAdd<XA, '0'>]>
: SplitB extends
? ReduceNum<'', Join<YB, true>, [...R, MetaAdd<'0', XB>]>
: R
// 地推进位
type Tee<T extends Array<number>, R extends string = '', CR extends string = '0'> = T extends [
infer A extends number,
...infer B extends Array<number>,
]
? ResolveNum<A> extends
? ResolveNum<MetaAdd<Y, CR>> extends
? Tee<B, `${_Y}${R}`, `${MetaAdd<X, _X>}`>
: never
: never
: CR extends '0'
? R
: `${CR}${R}`
// 判断是否合法
type IsValid<
T extends string,
Temp extends Array<string> = [],
SplitT extends Array<string> = Split<T>,
> = SplitT extends
? X extends MetaNum
? X extends '0'
? Temp['length'] extends 0
? SplitT['length'] extends 1
? true
: false
: IsValid<Join<Y>, [...Temp, X]>
: IsValid<Join<Y>, [...Temp, X]>
: false
: Temp['length'] extends 0
? false
: true
// 组合加法
type Add<A extends string, B extends string, IsValidA = IsValid<A>, IsValidB = IsValid<B>> = IsValidA extends IsValidB
? IsValidA extends true
? // @ts-ignore
Tee<ReduceNum<A, B>>
: never
: never
type Foo_1 = Add<'0', '1'>
type Foo_1_1 = Add<'0', ''>
type Foo_2 = Add<'1', '0'>
type Foo_3 = Add<'0', '0'>
type Foo_4 = Add<'123', '456'>
type Foo_5 = Add<'937', '9999999999999878'>
type Foo_6 = Add<'12846026972358281685236841339743503218625460074', '16738438016761768034928435260197280468667948046'>
页: [1]