diff --git a/src/types/util.ts b/src/types/util.ts index 8d77427c7..fb3512b89 100644 --- a/src/types/util.ts +++ b/src/types/util.ts @@ -1,117 +1,103 @@ -type UpperCaseCharacters = - | "A" - | "B" - | "C" - | "D" - | "E" - | "F" - | "G" - | "H" - | "I" - | "J" - | "K" - | "L" - | "M" - | "N" - | "O" - | "P" - | "Q" - | "R" - | "S" - | "T" - | "U" - | "V" - | "W" - | "X" - | "Y" - | "Z"; +export type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; + +export type WordSeparators = '-' | '_' | ' '; + +export type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; + +export type SplitIncludingDelimiters = + Source extends '' ? [] : + Source extends `${infer FirstPart}${Delimiter}${infer SecondPart}` ? + ( + Source extends `${FirstPart}${infer UsedDelimiter}${SecondPart}` + ? UsedDelimiter extends Delimiter + ? Source extends `${infer FirstPart}${UsedDelimiter}${infer SecondPart}` + ? [...SplitIncludingDelimiters, UsedDelimiter, ...SplitIncludingDelimiters] + : never + : never + : never + ) : + [Source]; -type WordSeparators = "-" | "_" | " "; -type SplitIncludingDelimiters< - Source extends string, - Delimiter extends string, -> = Source extends "" ? [] - : Source extends `${infer FirstPart}${Delimiter}${infer SecondPart}` ? ( - Source extends `${FirstPart}${infer UsedDelimiter}${SecondPart}` - ? UsedDelimiter extends Delimiter - ? Source extends `${infer FirstPart}${UsedDelimiter}${infer SecondPart}` - ? [ - ...SplitIncludingDelimiters, - UsedDelimiter, - ...SplitIncludingDelimiters, - ] - : never - : never - : never - ) - : [Source]; -type StringPartToDelimiterCase< - StringPart extends string, - UsedWordSeparators extends string, - UsedUpperCaseCharacters extends string, - Delimiter extends string, -> = StringPart extends UsedWordSeparators ? Delimiter - : StringPart extends UsedUpperCaseCharacters - ? `${Delimiter}${Lowercase}` - : StringPart; -type StringArrayToDelimiterCase< - Parts extends any[], - UsedWordSeparators extends string, - UsedUpperCaseCharacters extends string, - Delimiter extends string, -> = Parts extends [`${infer FirstPart}`, ...infer RemainingParts] - ? `${StringPartToDelimiterCase< - FirstPart, - UsedWordSeparators, - UsedUpperCaseCharacters, - Delimiter - >}${StringArrayToDelimiterCase< - RemainingParts, - UsedWordSeparators, - UsedUpperCaseCharacters, - Delimiter - >}` - : ""; -type DelimiterCase = Value extends string - ? StringArrayToDelimiterCase< - SplitIncludingDelimiters, - WordSeparators, - UpperCaseCharacters, - Delimiter - > - : Value; type InnerCamelCaseStringArray = - Parts extends [`${infer FirstPart}`, ...infer RemainingParts] - ? FirstPart extends undefined ? "" - : FirstPart extends "" - ? InnerCamelCaseStringArray - : `${PreviousPart extends "" ? FirstPart - : Capitalize}${InnerCamelCaseStringArray< - RemainingParts, - FirstPart - >}` - : ""; -type CamelCaseStringArray = Parts extends - [`${infer FirstPart}`, ...infer RemainingParts] ? Uncapitalize< - `${FirstPart}${InnerCamelCaseStringArray}` -> - : never; -type Split = string extends S ? string[] - : S extends "" ? [] - : S extends `${infer T}${D}${infer U}` ? [T, ...Split] - : [S]; + Parts extends [`${infer FirstPart}`, ...infer RemainingParts] + ? FirstPart extends undefined + ? '' + : FirstPart extends '' + ? InnerCamelCaseStringArray + : `${PreviousPart extends '' ? FirstPart : Capitalize}${InnerCamelCaseStringArray}` + : ''; -export type SnakeCase = DelimiterCase; -export type CamelCase = K extends string - ? CamelCaseStringArray> - : K; +type CamelCaseStringArray = + Parts extends [`${infer FirstPart}`, ...infer RemainingParts] + ? Uncapitalize<`${FirstPart}${InnerCamelCaseStringArray}`> + : never; -export type CamelCaseProps = { - [K in keyof T as CamelCase]: CamelCaseProps; -}; +type StringPartToDelimiterCase = + StringPart extends UsedWordSeparators ? Delimiter : + StringPart extends UsedUpperCaseCharacters ? `${Delimiter}${Lowercase}` : + StringPart; -export type SnakeCaseProps = { - [K in keyof T as SnakeCase]: SnakeCaseProps; -}; +type StringArrayToDelimiterCase = + Parts extends [`${infer FirstPart}`, ...infer RemainingParts] + ? `${StringPartToDelimiterCase}${StringArrayToDelimiterCase}` + : ''; + +export type DelimiterCase = Value extends string + ? StringArrayToDelimiterCase< + SplitIncludingDelimiters, + WordSeparators, + UpperCaseCharacters, + Delimiter + > + : Value; + +export type DelimiterCasedProperties< + Value, + Delimiter extends string +> = Value extends Function + ? Value + : Value extends Array + ? Value + : { [K in keyof Value as DelimiterCase]: Value[K] }; + +export type DelimiterCasedPropertiesDeep< + Value, + Delimiter extends string +> = Value extends Function + ? Value + : Value extends Array + ? Array> + : Value extends Set + ? Set> : { + [K in keyof Value as DelimiterCase< + K, + Delimiter + >]: DelimiterCasedPropertiesDeep; + }; + +export type SnakeCase = DelimiterCase; + +export type CamelCase = K extends string ? CamelCaseStringArray> : K; + +export type SnakeCasedProperties = DelimiterCasedProperties; + +export type CamelCasedProperties = Value extends Function + ? Value + : Value extends Array + ? Value + : { + [K in keyof Value as CamelCase]: Value[K]; + }; + +export type SnakeCasedPropertiesDeep = DelimiterCasedPropertiesDeep; + +export type CamelCasedPropertiesDeep = Value extends Function + ? Value + : Value extends Array + ? Array> + : Value extends Set + ? Set> : { + [K in keyof Value as CamelCase]: CamelCasedPropertiesDeep; + };