@blueprintjs/icons
Version:
Components, fonts, icons, and css files for creating and displaying icons.
106 lines (87 loc) • 3.23 kB
text/typescript
import type { UpperCaseCharacters, WordSeparators } from "./sourceUtilities";
/**
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.
@category Template Literals
*/
export 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<FirstPart, Delimiter>,
UsedDelimiter,
...SplitIncludingDelimiters<SecondPart, Delimiter>,
]
: never
: never
: never
: [Source];
/**
Format a specific part of the splitted string literal that `StringArrayToDelimiterCase<>` fuses together, ensuring desired casing.
@see StringArrayToDelimiterCase
*/
type StringPartToDelimiterCase<
StringPart extends string,
UsedWordSeparators extends string,
UsedUpperCaseCharacters extends string,
Delimiter extends string,
> = StringPart extends UsedWordSeparators
? Delimiter
: StringPart extends UsedUpperCaseCharacters
? `${Delimiter}${Lowercase<StringPart>}`
: StringPart;
/**
Takes the result of a splitted string literal and recursively concatenates it together into the desired casing.
It receives `UsedWordSeparators` and `UsedUpperCaseCharacters` as input to ensure it's fully encapsulated.
@see SplitIncludingDelimiters
*/
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>}`
: "";
/**
Convert a string literal to a custom string delimiter casing.
This can be useful when, for example, converting a camel-cased object property to an oddly cased one.
@see KebabCase
@see SnakeCase
@example
```
import {DelimiterCase} from 'type-fest';
// Simple
const someVariable: DelimiterCase<'fooBar', '#'> = 'foo#bar';
// Advanced
type OddlyCasedProperties<T> = {
[K in keyof T as DelimiterCase<K, '#'>]: T[K]
};
interface SomeOptions {
dryRun: boolean;
includeFile: string;
foo: number;
}
const rawCliOptions: OddlyCasedProperties<SomeOptions> = {
'dry#run': true,
'include#file': 'bar.js',
foo: 123
};
```
@category Template Literals
*/
export type DelimiterCase<Value, Delimiter extends string> = Value extends string
? StringArrayToDelimiterCase<
SplitIncludingDelimiters<Value, WordSeparators | UpperCaseCharacters>,
WordSeparators,
UpperCaseCharacters,
Delimiter
>
: Value;