import type { Extends } from './expression';
/**
 * Alias for any literal type (useful for template string parameters)
 *
 * @see {@link Split}
 * @see {@link Suffix}
 * @see {@link Prefix}
 * @see {@link StartsWith}
 * @see {@link EndsWith}
 */
export type Literal = string | number | bigint | boolean;
/**
 * Ensures that a string is not empty.
 *
 * @template T - The type that extends a string.
 *
 * @example
 * // T is assigned a string type
 * type A = NonEmpty<string>;
 * // A can be any string except the empty string
 * let a: A = "hello"; // Valid
 * a = ""; // Error: Type '""' is not assignable to type 'NonEmpty<string>'
 *
 * @example
 * // T is assigned a string literal type
 * type B = NonEmpty<"hello">;
 * // B can only be "hello"
 * let b: B = "hello"; // Valid
 * b = ""; // Error: Type '""' is not assignable to type 'NonEmpty<"hello">'
 */
export type NonEmpty<T extends string> = T extends '' ? never : T;
/**
 * Splits a given string ({@link TValue}) around occurrences of a given separator ({@link TSeparator}).
 *
 * The resulting type is an array where each item is a part of the original string that falls between two instances of the separator.
 *
 * If the string does not contain the separator, the array will contain just the original string.
 *
 * If the string is empty, the result is an empty array.
 *
 * @template TValue - The string to split. Must extend `string`.
 * @template TSeparator - The character(s) used to determine in which locations the string should be split. Must be a `string`.
 *
 * @example
 *
 * ```typescript
 *  type Example = Split<'a.b.c.d', '.'>;  // Output will be: ['a', 'b', 'c', 'd']
 * ```
 * In the above example, the string 'a.b.c.d' is split around occurrences of the '.' separator.
 *
 * @example
 *
 * ```typescript
 *  type ExampleUnion = Split<'a.b-c', '.' | '-'>;  // Output will be: ['a', 'b-c'] | ['a.b', 'c']
 * ```
 * The split operation will distribute the union members and create two possible return type for the union
 */
export type Split<TValue extends string, TSeparator extends string> = {
    [TSep in TSeparator]: TValue extends `${infer TLeft}${TSep}${infer TRight}` ? [TLeft, ...Split<TRight, TSep>] : TValue extends '' ? [] : [TValue];
}[TSeparator];
/**
 * The `Suffix` type appends a literal suffix ({@link TSuffix}) to the end of a provided string ({@link TValue}).
 *
 * @template TValue - The string to add the suffix to.
 * @template TSuffix - It extends the {@link Literal} type, and represents the suffix to append.
 *
 * @example
 * ```typescript
 * // A type that appends '.com' to a string
 * type DomainName = Suffix<string, '.com'>;
 * const myComDomain: DomainName = 'example.com'; // This is valid
 * const myNetDomain: DomainName = 'example.net'; // This is not valid
 *
 * // A variant using `number` as literal
 * type SuffixedNumber = Suffix<string, 1>;
 * const mySuffixedNumber: SuffixedNumber = 'example1'; // Also valid
 * ```
 */
export type Suffix<TValue extends string, TSuffix extends Literal> = `${TValue}${TSuffix}`;
/**
 * Prepend a literal prefix ({@link TPrefix}) to the start of a provided string ({@link TValue}).
 *
 * @template TValue - The string to add the prefix to.
 * @template TPrefix - It extends the {@link Literal} type, and represents the prefix to prepend.
 *
 * @example
 * ```typescript
 * // A type that prepends 'Hello ' to a string
 * type Greeting = Suffix<string, 'Hello '>;
 * const greeting: Greeting = 'Hello Bob'; // This is valid
 * const farewell: Greeting = 'Bye Bob'; // This is not valid
 * ```
 */
export type Prefix<TValue extends string, TPrefix extends Literal> = `${TPrefix}${TValue}`;
/**
 * Creates an indexed object where every key is a string and every value is `T`
 *
 * @template T - Value type of the dictionary
 *
 * @example
 * // Dictionary where each key is a string and is bound to a number type value.
 * const numDict: Dict<number> = {
 *   'a': 1,
 *   'b': 2,
 *   'c': 3
 * };
 */
export type Dict<T> = {
    [key: string]: T;
};
/**
 * Determines if a string, represented by {@link TValue}, ends with a specific literal ({@link TSuffix}).
 *
 * @template TValue - The string to check.
 * @template TSuffix - A literal which may or may not be at the end of {@link TValue}.
 *
 * @remark
 * To remember easily: `String.prototype.endsWith` method but at type level.
 *
 * @example
 * ```typescript
 * type Result = EndsWith<"HelloWorld", "World">;
 * // Output: Constants.True
 * ```
 *
 * ```typescript
 * type Result = EndsWith<"HelloWorld", "Hello">;
 * // Output: Constants.False
 * ```
 */
export type EndsWith<TValue extends string, TSuffix extends Literal> = Extends<TValue, `${string}${TSuffix}`>;
/**
 * Determines if a string, represented by {@link TValue}, starts with a specific literal ({@link TPrefix}).
 *
 * @template TValue - The string to check.
 * @template TPrefix - A literal which may or may not be at the start of {@link TValue}.
 *
 * @remark
 * To remember easily: `String.prototype.startsWith` method but at type level.
 *
 * @example
 * ```typescript
 * type IsHelloWorld = StartsWith<"Hello World", "Hello">;
 * // Output: Constants.True
 * ```
 *
 * @example
 * ```typescript
 * type NotHelloWorld = StartsWith<"World Hello", "Hello">;
 * // Output: Constants.False
 * ```
 */
export type StartsWith<TValue extends string, TPrefix extends Literal> = Extends<TValue, `${TPrefix}${string}`>;
/**
 * Combines a union of literal types with a more general type while preserving autocompletion.
 *
 * When using string literal unions, it maintains IDE suggestions for the literal values while
 * still allowing any value of the base type.
 *
 * @template T - The literal type to suggest in autocompletion (for example, specific strings)
 * @template U - The base type that T extends from (defaults to string)
 *
 * @example
 * // Define a type for specific HTTP methods while allowing custom one's
 * type HttpMethod = LiteralUnion<'GET' | 'POST' | 'PUT' | 'DELETE'>;
 *
 * // These will show up in autocompletion
 * const method1: HttpMethod = 'GET';     // ✓ Valid
 * const method2: HttpMethod = 'POST';    // ✓ Valid
 *
 * // This is also valid since any string is allowed
 * const method3: HttpMethod = 'PATCH';   // ✓ Valid
 *
 * @example
 * // Can be used with number literals too
 * type CommonPorts = LiteralUnion<80 | 443 | 3000, number>;
 *
 * // Suggested in autocompletion
 * const port1: CommonPorts = 80;         // ✓ Valid
 * const port2: CommonPorts = 443;        // ✓ Valid
 *
 * // Any number is still accepted
 * const port3: CommonPorts = 8080;       // ✓ Valid
 *
 * @remark
 * This type is particularly useful for API parameters where specific values should be suggested,
 * but custom values shouldn't be restricted.
 */
export type LiteralUnion<T extends U, U = string> = T | (U & NonNullable<unknown>);
//# sourceMappingURL=string.d.ts.map