编辑 | blame | 历史 | 原始文档
import {UpperCaseCharacters, WordSeparators} from '../source/utilities';

/**
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.
*/
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];

/**
Format a specific part of the splitted string literal that `StringArrayToDelimiterCase<>` fuses together, ensuring desired casing.

@see StringArrayToDelimiterCase
*/
type StringPartToDelimiterCase =
	StringPart extends UsedWordSeparators ? Delimiter :
	StringPart extends UsedUpperCaseCharacters ? `${Delimiter}${Lowercase}` :
	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 [`${infer FirstPart}`, ...infer RemainingParts]
		? `${StringPartToDelimiterCase}${StringArrayToDelimiterCase}`
		: '';

/**
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 OddlyCasedProps = {
	[K in keyof T as DelimiterCase]: T[K]
};

interface SomeOptions {
	dryRun: boolean;
	includeFile: string;
	foo: number;
}

const rawCliOptions: OddlyCasedProps = {
	'dry#run': true,
	'include#file': 'bar.js',
	foo: 123
};
```
*/

export type DelimiterCase = Value extends string
	? StringArrayToDelimiterCase<
		SplitIncludingDelimiters,
		WordSeparators,
		UpperCaseCharacters,
		Delimiter
	>
	: Value;