[6a3a178] | 1 | import {UpperCaseCharacters, WordSeparators} from '../source/utilities';
|
---|
| 2 |
|
---|
| 3 | /**
|
---|
| 4 | Unlike a simpler split, this one includes the delimiter splitted on in the resulting array literal. This is to enable splitting on, for example, upper-case characters.
|
---|
| 5 | */
|
---|
| 6 | export type SplitIncludingDelimiters<Source extends string, Delimiter extends string> =
|
---|
| 7 | Source extends '' ? [] :
|
---|
| 8 | Source extends `${infer FirstPart}${Delimiter}${infer SecondPart}` ?
|
---|
| 9 | (
|
---|
| 10 | Source extends `${FirstPart}${infer UsedDelimiter}${SecondPart}`
|
---|
| 11 | ? UsedDelimiter extends Delimiter
|
---|
| 12 | ? Source extends `${infer FirstPart}${UsedDelimiter}${infer SecondPart}`
|
---|
| 13 | ? [...SplitIncludingDelimiters<FirstPart, Delimiter>, UsedDelimiter, ...SplitIncludingDelimiters<SecondPart, Delimiter>]
|
---|
| 14 | : never
|
---|
| 15 | : never
|
---|
| 16 | : never
|
---|
| 17 | ) :
|
---|
| 18 | [Source];
|
---|
| 19 |
|
---|
| 20 | /**
|
---|
| 21 | Format a specific part of the splitted string literal that `StringArrayToDelimiterCase<>` fuses together, ensuring desired casing.
|
---|
| 22 |
|
---|
| 23 | @see StringArrayToDelimiterCase
|
---|
| 24 | */
|
---|
| 25 | type StringPartToDelimiterCase<StringPart extends string, UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> =
|
---|
| 26 | StringPart extends UsedWordSeparators ? Delimiter :
|
---|
| 27 | StringPart extends UsedUpperCaseCharacters ? `${Delimiter}${Lowercase<StringPart>}` :
|
---|
| 28 | StringPart;
|
---|
| 29 |
|
---|
| 30 | /**
|
---|
| 31 | Takes the result of a splitted string literal and recursively concatenates it together into the desired casing.
|
---|
| 32 |
|
---|
| 33 | It receives `UsedWordSeparators` and `UsedUpperCaseCharacters` as input to ensure it's fully encapsulated.
|
---|
| 34 |
|
---|
| 35 | @see SplitIncludingDelimiters
|
---|
| 36 | */
|
---|
| 37 | type StringArrayToDelimiterCase<Parts extends any[], UsedWordSeparators extends string, UsedUpperCaseCharacters extends string, Delimiter extends string> =
|
---|
| 38 | Parts extends [`${infer FirstPart}`, ...infer RemainingParts]
|
---|
| 39 | ? `${StringPartToDelimiterCase<FirstPart, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}${StringArrayToDelimiterCase<RemainingParts, UsedWordSeparators, UsedUpperCaseCharacters, Delimiter>}`
|
---|
| 40 | : '';
|
---|
| 41 |
|
---|
| 42 | /**
|
---|
| 43 | Convert a string literal to a custom string delimiter casing.
|
---|
| 44 |
|
---|
| 45 | This can be useful when, for example, converting a camel-cased object property to an oddly cased one.
|
---|
| 46 |
|
---|
| 47 | @see KebabCase
|
---|
| 48 | @see SnakeCase
|
---|
| 49 |
|
---|
| 50 | @example
|
---|
| 51 | ```
|
---|
| 52 | import {DelimiterCase} from 'type-fest';
|
---|
| 53 |
|
---|
| 54 | // Simple
|
---|
| 55 |
|
---|
| 56 | const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar';
|
---|
| 57 |
|
---|
| 58 | // Advanced
|
---|
| 59 |
|
---|
| 60 | type OddlyCasedProps<T> = {
|
---|
| 61 | [K in keyof T as DelimiterCase<K, '#'>]: T[K]
|
---|
| 62 | };
|
---|
| 63 |
|
---|
| 64 | interface SomeOptions {
|
---|
| 65 | dryRun: boolean;
|
---|
| 66 | includeFile: string;
|
---|
| 67 | foo: number;
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | const rawCliOptions: OddlyCasedProps<SomeOptions> = {
|
---|
| 71 | 'dry#run': true,
|
---|
| 72 | 'include#file': 'bar.js',
|
---|
| 73 | foo: 123
|
---|
| 74 | };
|
---|
| 75 | ```
|
---|
| 76 | */
|
---|
| 77 |
|
---|
| 78 | export type DelimiterCase<Value, Delimiter extends string> = Value extends string
|
---|
| 79 | ? StringArrayToDelimiterCase<
|
---|
| 80 | SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>,
|
---|
| 81 | WordSeparators,
|
---|
| 82 | UpperCaseCharacters,
|
---|
| 83 | Delimiter
|
---|
| 84 | >
|
---|
| 85 | : Value;
|
---|