UNPKG

type-samurai

Version:

Advanced utility types for Typescript

128 lines (121 loc) 3.74 kB
import { IsEmptyString } from "./string"; import { Sum } from "./sum"; type _StringLength< S extends string, Parts extends [string[], string[], string[], string[]] = [[], [], [], []] > = S extends "" ? Sum< Sum<Parts[0]["length"], Parts[1]["length"]>, Sum<Parts[2]["length"], Parts[3]["length"]> > : S extends `${infer C1 extends string}${infer Rest1 extends string}` ? Rest1 extends `${infer C2 extends string}${infer Rest2 extends string}` ? Rest2 extends `${infer C3 extends string}${infer Rest3 extends string}` ? Rest3 extends `${infer C4 extends string}${infer Rest4 extends string}` ? _StringLength< Rest4, [ [...Parts[0], C1], [...Parts[1], C2], [...Parts[2], C3], [...Parts[3], C4] ] > : _StringLength< Rest3, [[...Parts[0], C1], [...Parts[1], C2], [...Parts[2], C3], Parts[3]] > : _StringLength< Rest2, [[...Parts[0], C1], [...Parts[1], C2], Parts[2], Parts[3]] > : _StringLength<Rest1, [[...Parts[0], C1], Parts[1], Parts[2], Parts[3]]> : _StringLength<S, Parts>; /** * Returns the length of the passed string. Range of string length `[0, 3968]` * @example * ```ts * // 0 * type Case1 = StringLength<''> * // 3 * type Case2 = StringLength<'xxx'> * ``` */ export type StringLength<S extends string> = _StringLength<S>; /** * Accepts two strings, returns the third argument (defaults to `never`) if the first string is shorter, otherwise returns the fourth argument (defaults to `never`) if the second argument is shorter, if strings have the same length returns the fifth argument (defaults to `never`) * @example * ```ts * // 'first shorter' * type Case1 = CompareStringLength<'a', 'ab', 'first shorter'> * // 'first longer' * type Case2 = CompareStringLength<'abc', 'ab', 'first shorter', 'first longer'> * // 'equal' * type Case3 = CompareStringLength<'ab', 'ab', 'first shorter', 'first longer', 'equal'> * ``` */ export type CompareStringLength< Str1 extends string, Str2 extends string, IfStr1Shorter = never, IfStr2Shorter = never, IfEqual = never > = IsEmptyString<Str1> extends true ? IsEmptyString<Str2> extends true ? IfEqual : IfStr1Shorter : IsEmptyString<Str2> extends true ? IfStr2Shorter : Str1 extends `${string}${infer Str1Rest extends string}` ? Str2 extends `${string}${infer Str2Rest extends string}` ? CompareStringLength< Str1Rest, Str2Rest, IfStr1Shorter, IfStr2Shorter, IfEqual > : never : never; /** * Accepts two strings, returns a boolean whether the first string is shorter * @example * ```ts * // true * type Case1 = IsShorterString<'a', 'ab'> * // false * type Case2 = IsShorterString<'abc', 'ab'> * ``` */ export type IsShorterString< Str1 extends string, Str2 extends string > = CompareStringLength<Str1, Str2, true, false, false>; /** * Accepts two strings, returns a boolean whether the first string is longer * @example * ```ts * // true * type Case1 = IsLongerString<'ab', 'a'> * // false * type Case2 = IsLongerString<'a', 'ab'> * ``` */ export type IsLongerString< Str1 extends string, Str2 extends string > = CompareStringLength<Str1, Str2, false, true, false>; /** * Accepts two strings, returns a boolean whether strings have the same length * @example * ```ts * // true * type Case1 = IsSameLengthString<'ab', 'ab'> * // false * type Case2 = IsSameLengthString<'ab', 'abc'> * ``` */ export type IsSameLengthString< Str1 extends string, Str2 extends string > = CompareStringLength<Str1, Str2, false, false, true>;