Created
June 20, 2023 15:16
-
-
Save zRains/98dabb64760dbc01ce1d0b54eeb8cb19 to your computer and use it in GitHub Desktop.
Thousand separator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 判断类型是否相等 | |
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false | |
// 条件判断 | |
type If<C extends boolean, T, F> = C extends true ? T : F | |
// 获取类型数组最后一个类型 | |
type LastEl<T extends string[]> = T extends [...infer _P, infer K] ? K : never | |
// 合法数字表达集合 | |
type Numeric = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-' | '.' | |
// 字符串转为字符数组(反转) | |
type StrToArr<T extends string, R extends string[] = []> = T extends `${infer A}${infer B}` ? StrToArr<B, [A, ...R]> : R | |
// 字符串长度 | |
type StrLen<T extends string> = StrToArr<T>['length'] | |
// 字符数组转字符串 | |
type JoinStr<T extends string[], R extends string = ''> = T extends [...infer A, infer B] | |
? `${Extract<B, string>}${JoinStr<Extract<A, string[]>, R>}` | |
: R | |
// 判断负号(-)位置是否合法 | |
type IsValidPrefix<Char extends string, Idx extends number> = Char extends '-' ? Equal<Idx, 0> : true | |
// 判断小数点(.)是否合法 | |
type IsValidDot< | |
Char extends string, | |
CharArr extends string[], | |
DotArr extends string[], | |
Len extends number, | |
> = Char extends '.' | |
? If< | |
Equal<CharArr['length'], 0>, | |
false, | |
If< | |
Equal<LastEl<CharArr>, '-'>, | |
false, | |
If<Equal<[...CharArr, Char]['length'], Len>, false, Equal<DotArr['length'], 0>> | |
> | |
> | |
: true | |
// 判断是否为合法数字表达字符串 | |
type IsNumericStr< | |
Str extends string, | |
CharArr extends string[] = [], | |
DotArr extends string[] = [], | |
Len extends number = StrLen<Str>, | |
> = Str extends `${infer Char}${infer RestStr}` | |
? Char extends Numeric | |
? If< | |
Equal<IsValidPrefix<Char, CharArr['length']> & IsValidDot<Char, CharArr, DotArr, Len>, true>, | |
IsNumericStr<RestStr, [...CharArr, Char], If<Equal<Char, '.'>, [...DotArr, '.'], DotArr>, Len>, | |
false | |
> | |
: false | |
: If<Equal<Len, 0>, false, If<Equal<Len, 1>, If<Equal<Str, '.'>, false, If<Equal<Str, '-'>, false, true>>, true>> | |
// 字符串分隔 | |
type NumSeparate<T extends string[], R extends string = ''> = T extends [infer A, infer B, infer C, ...infer D] | |
? `${NumSeparate< | |
Extract<D, string[]>, | |
`${Extract<C, string>}${Extract<B, string>}${Extract<A, string>}${If<Equal<R, ''>, '', `,${R}`>}` | |
>}` | |
: If<Equal<T['length'], 0>, R, `${JoinStr<T>}${If<Equal<R, ''>, '', `,${R}`>}`> | |
type Separate<T extends string> = If< | |
IsNumericStr<T>, | |
T extends `-${infer A}.${infer B}` | |
? `-${NumSeparate<StrToArr<A>>}.${B}` | |
: T extends `-${infer B}` | |
? `-${NumSeparate<StrToArr<B>>}` | |
: T extends `${infer C}.${infer D}` | |
? `${NumSeparate<StrToArr<C>>}.${D}` | |
: NumSeparate<StrToArr<T>>, | |
never | |
> | |
type A = Separate<'121241'> // 121,241 | |
type B = Separate<'121342.41'> // 121,342.41 | |
type C = Separate<'-3526235236'> // -3,526,235,236 | |
type D = Separate<'-2213a'> // never | |
type E = Separate<'-35262352.36'> // -35,262,352.36 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment