Skip to content

Instantly share code, notes, and snippets.

@zRains
Created June 20, 2023 15:16
Show Gist options
  • Save zRains/98dabb64760dbc01ce1d0b54eeb8cb19 to your computer and use it in GitHub Desktop.
Save zRains/98dabb64760dbc01ce1d0b54eeb8cb19 to your computer and use it in GitHub Desktop.
Thousand separator.
// 判断类型是否相等
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