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;
|
---|