diff --git a/package-lock.json b/package-lock.json index 20fd581..de13dfc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "string-literal-list", - "version": "1.22.0", + "version": "1.23.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "string-literal-list", - "version": "1.22.0", + "version": "1.23.0", "license": "MIT", "devDependencies": { "@types/node": "latest", diff --git a/package.json b/package.json index 1f2085b..f2ca681 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "string-literal-list", - "version": "1.22.0", + "version": "1.23.0", "description": "an array for string literal", "main": "stringList.cjs", "module": "stringList.js", @@ -11,14 +11,14 @@ "types": "stringList.d.ts", "exports": { ".": { - "types": "./stringList.js", + "types": "./stringList.d.ts", "require": "./stringList.cjs", "node": "./stringList.js", "import": "./stringList.min.js", "default": "./stringList.js" }, "./strict.js": { - "types": "./strict.js", + "types": "./strict.d.ts", "require": "./strict.cjs", "node": "./strict.js", "import": "./strict.min.js", @@ -28,7 +28,7 @@ "default": "./types/index.js" }, "./stringList.js": { - "types": "./stringList.js", + "types": "./stringList.d.ts", "require": "./stringList.cjs", "node": "./stringList.js", "import": "./stringList.min.js", diff --git a/strict.d.ts b/strict.d.ts index b433d61..2bf836b 100644 --- a/strict.d.ts +++ b/strict.d.ts @@ -1,9 +1,7 @@ -import { IStringList } from './types/list.js'; +export declare function stringList< + TT extends readonly string[] = readonly never[], +>(...strings: TT): StringLiteralList.list.IStringList; -export function stringList( +export declare function sl( ...strings: TT -): IStringList; - -export function sl( - ...strings: TT -): IStringList; +): StringLiteralList.list.IStringList; diff --git a/stringList.d.ts b/stringList.d.ts index ba6b4f6..6b5b7e8 100644 --- a/stringList.d.ts +++ b/stringList.d.ts @@ -1,9 +1,7 @@ -import { IStringList } from './types/list.js'; +export declare function stringList< + TT extends readonly string[] = readonly never[], +>(...strings: TT): StringLiteralList.list.IStringList; -export function stringList( +export declare function sl( ...strings: TT -): IStringList; - -export function sl( - ...strings: TT -): IStringList; +): StringLiteralList.list.IStringList; diff --git a/stringListFunction.d.ts b/stringListFunction.d.ts index bdc452b..7be53c7 100644 --- a/stringListFunction.d.ts +++ b/stringListFunction.d.ts @@ -1,12 +1,10 @@ /// /// -import { IStringList } from './types/list.js'; - -export function stringListMutable< +export declare function stringListMutable< TT extends readonly string[] = readonly never[], ->(...list: TT): IStringList; +>(...list: TT): StringLiteralList.list.IStringList; -export function stringListReadonly< +export declare function stringListReadonly< TT extends readonly string[] = readonly never[], ->(...list: TT): IStringList; +>(...list: TT): StringLiteralList.list.IStringList; diff --git a/types/generic.d.ts b/types/generic.d.ts index 48ff3c4..171761e 100644 --- a/types/generic.d.ts +++ b/types/generic.d.ts @@ -2,92 +2,91 @@ import './index.js'; declare global { - export namespace StringLiteralList { - export namespace generic { - /** - * Returns a tuple of the given length with the given type. - */ - export type TupleOf< - L extends number, - T = unknown, - result extends any[] = [], - > = result['length'] extends L ? result : TupleOf; + export namespace StringLiteralList {} + export namespace StringLiteralList.generic { + /** + * Returns a tuple of the given length with the given type. + */ + export type TupleOf< + L extends number, + T = unknown, + result extends any[] = [], + > = result['length'] extends L ? result : TupleOf; - export type Subtract = number extends - | A - | B - ? number - : TupleOf extends [...infer U, ...TupleOf] - ? U['length'] - : 0; + export type Subtract = number extends + | A + | B + ? number + : TupleOf extends [...infer U, ...TupleOf] + ? U['length'] + : 0; - export type IsNegative = number extends T - ? boolean - : `${T}` extends `-${number}` - ? true - : false; + export type IsNegative = number extends T + ? boolean + : `${T}` extends `-${number}` + ? true + : false; - export type Abs = - `${T}` extends `-${infer U extends number}` ? U : T; + export type Abs = + `${T}` extends `-${infer U extends number}` ? U : T; - /** - * Returns true if input number type is a literal - */ - export type IsNumberLiteral = [T] extends [number] - ? [number] extends [T] - ? false - : true - : false; + /** + * Returns true if input number type is a literal + */ + export type IsNumberLiteral = [T] extends [number] + ? [number] extends [T] + ? false + : true + : false; - export type IsBooleanLiteral = [T] extends [boolean] - ? [boolean] extends [T] - ? false - : true - : false; + export type IsBooleanLiteral = [T] extends [boolean] + ? [boolean] extends [T] + ? false + : true + : false; - /** - * Returns true if any elements in boolean array are the literal true (not false or boolean) - */ - export type Any = Arr extends [ - infer Head extends boolean, - ...infer Rest extends boolean[], - ] - ? IsBooleanLiteral extends true - ? Head extends true - ? true - : Any + /** + * Returns true if any elements in boolean array are the literal true (not false or boolean) + */ + export type Any = Arr extends [ + infer Head extends boolean, + ...infer Rest extends boolean[], + ] + ? IsBooleanLiteral extends true + ? Head extends true + ? true : Any - : false; + : Any + : false; - export type Reject< - tuple, - cond, - output extends any[] = [], - > = tuple extends [infer first, ...infer rest] - ? Reject - : output; + export type Reject = tuple extends [ + infer first, + ...infer rest, + ] + ? Reject + : output; - /** - * Returns true if every element in boolean array is the literal true (not false or boolean) - */ - export type All = - IsBooleanLiteral extends true - ? Arr extends [ - infer Head extends boolean, - ...infer Rest extends boolean[], - ] - ? Head extends true - ? Any - : false // Found `false` in array - : true // Empty array (or all elements have already passed test) - : false; // Array/Tuple contains `boolean` type + /** + * Returns true if every element in boolean array is the literal true (not false or boolean) + */ + export type All = + IsBooleanLiteral extends true + ? Arr extends [ + infer Head extends boolean, + ...infer Rest extends boolean[], + ] + ? Head extends true + ? Any + : false // Found `false` in array + : true // Empty array (or all elements have already passed test) + : false; // Array/Tuple contains `boolean` type - export type UnionToIntersection = ( - U extends never ? never : (arg: U) => never - ) extends (arg: infer I) => void - ? I - : never; - } + export type UnionToIntersection = ( + U extends never ? never : (arg: U) => never + ) extends (arg: infer I) => void + ? I + : never; } } + export {}; diff --git a/types/index.d.ts b/types/index.d.ts index e6168a4..5a705f0 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,18 +7,7 @@ import { ArrayInPlaceMutation } from '../StringLiteralList.js'; declare global { - export namespace StringLiteralList { - // @ts-ignore - export * as tuple from './tuple.js'; - // @ts-ignore - export * as list from './list.js'; - // @ts-ignore - export * as record from './record.js'; - // @ts-ignore - export * as string from './string.js'; - // @ts-ignore - export * as generic from './generic.js'; - } + export namespace StringLiteralList {} export namespace specs { /** diff --git a/types/list.d.ts b/types/list.d.ts index 1a2558c..95cd8ee 100644 --- a/types/list.d.ts +++ b/types/list.d.ts @@ -1,518 +1,574 @@ -import { sl } from './index.js'; - -export interface ILiterals { - /** - * Namespace to expose the type inference. - * The values are undefined and should not be used other than type inference. - */ - infered: { - Tuple: Tuple; - TooLong: sl.string.Length<`${Tuple['length']}`> extends 5 | 6 | 7 | 8 - ? true - : false; - }; -} - -export type MaybeReadonly = [IsMutable] extends [ - true, -] - ? A - : Readonly; - -type RecordTypes = { - any: any; - string: string; - number: number; - boolean: boolean; - 'string|number': string | number; - 'number|boolean': number | boolean; - 'any[]': any[]; - 'string[]': string[]; - 'number[]': number[]; - 'boolean[]': boolean[]; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; - 'Record': Record; -}; - -type RecordType = keyof RecordTypes; - -export interface IStringList< - Tuple extends readonly string[] = readonly never[], - Mut extends boolean = true, - Unsorted extends boolean = false, -> extends Omit, specs.ImplementedMethod>, - ILiterals { - // Custom Methods - withPrefix

( - prefix: P, - ): sl.tuple.TuplePrefixed< - Tuple, - P extends string ? P : '', - [] - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - - withSuffix

( - suffix: P, - ): P extends string - ? sl.tuple.TupleSuffixed< +declare global { + namespace StringLiteralList {} + namespace StringLiteralList.list { + export interface ILiterals< + Tuple extends readonly string[] = readonly never[], + > { + /** + * Namespace to expose the type inference. + * The values are undefined and should not be used other than type inference. + */ + infered: { + Tuple: Tuple; + TooLong: StringLiteralList.string.Length<`${Tuple['length']}`> extends + | 5 + | 6 + | 7 + | 8 + ? true + : false; + }; + } + + export type MaybeReadonly = [ + IsMutable, + ] extends [true] + ? A + : Readonly; + + type RecordTypes = { + any: any; + string: string; + number: number; + boolean: boolean; + 'string|number': string | number; + 'number|boolean': number | boolean; + 'any[]': any[]; + 'string[]': string[]; + 'number[]': number[]; + 'boolean[]': boolean[]; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + 'Record': Record; + }; + + type RecordType = keyof RecordTypes; + + export interface IStringList< + Tuple extends readonly string[] = readonly never[], + Mut extends boolean = true, + Unsorted extends boolean = false, + > extends Omit, specs.ImplementedMethod>, + ILiterals { + // Custom Methods + withPrefix

( + prefix: P, + ): StringLiteralList.tuple.TuplePrefixed< Tuple, P extends string ? P : '', [] > extends infer W extends readonly string[] - ? MaybeReadonly> - : never - : never; - - // withDerivatedSuffix( - // chars: S, - // ): - // | T - // | sl.string.DropSuffix< - // sl.string.DropSuffix<`${T}${S}${S}`, S>, - // `${S}${S}` - // > extends infer W extends string - // ? MaybeReadonly> - // : never; - - // withDerivatedPrefix( - // chars: S, - // ): - // | T - // | sl.string.DropPrefix< - // sl.string.DropPrefix<`${S}${S}${T}`, S>, - // `${S}${S}` - // > extends infer W extends string - // ? MaybeReadonly> - // : never; - - withReplace( - searchValue: S, - replaceValue: D, - ): sl.tuple.TupleWithReplace extends infer W extends - readonly string[] - ? MaybeReadonly> - : never; - - withReplaceAll( - searchValue: S, - replaceValue: D, - ): sl.tuple.TupleWithReplace extends infer W extends - readonly string[] - ? MaybeReadonly> - : never; - - withTrim(): sl.tuple.TupleWithTrim extends infer W extends - readonly string[] - ? MaybeReadonly> - : never; - toLowerCase(): sl.tuple.TupleWithCaseTransform< - Tuple, - 'lowercase', - [] - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - toUpperCase(): sl.tuple.TupleWithCaseTransform< - Tuple, - 'uppercase', - [] - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - toCapitalize(): sl.tuple.TupleWithCaseTransform< - Tuple, - 'capitalize', - [] - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - toUnCapitalize(): sl.tuple.TupleWithCaseTransform< - Tuple, - 'unCapitalize', - [] - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - - value(val): Tuple[number]; - mutable(): (Tuple[number] & string)[]; - sort( - compareFn?: (a: P1, b: P2) => number, - ): MaybeReadonly>; - - reverse(): sl.tuple.TupleReversed extends infer W extends - readonly string[] - ? MaybeReadonly> - : this; - - without( - ...arg: readonly (ILiterals | S)[] - ): sl.tuple.TupleWithExclude extends infer E extends - readonly string[] - ? MaybeReadonly> - : never; - - toSorted( - compareFn?: (a: Tuple[number], b: Tuple[number]) => number, - ): MaybeReadonly>; - - toReversed(): sl.tuple.TupleReversed extends infer W extends - readonly string[] - ? MaybeReadonly> - : never; - - /** - * @deprecated This method does not support type inference, - * use `list.concat('str', 'str')` or `list.concatList(stringList('str','str'))` instead. - */ - concat( - ...arg: S[] - ): [...Tuple, S[number][number]] extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - - concat( - ...arg: S - ): [...Tuple, ...S] extends infer W extends readonly string[] - ? MaybeReadonly< - Mut, - IStringList - > - : never; - - concatList( - arg: ILiterals, - ): S extends infer C extends readonly string[] - ? readonly [...Tuple, ...C] extends infer W extends readonly string[] - ? MaybeReadonly> - : this - : this; - - toRecordType< - RT extends RecordType = 'any', - R extends Record[] = [], - >( - type?: RT, - initial?: RecordTypes[RT], - ...records: R - ): sl.record.Merge<[Record, ...R]>; - - toRecordValue( - initial?: V, - ...records: R - ): R[number] extends never - ? Record - : sl.record.Merge<[Record, ...R]>; - - // Readonly overrides - readonly length: [Unsorted] extends [true] ? number : Tuple['length']; - readonly [n: number]: Tuple[number] | undefined; - readonly enum: { [P in Tuple[number]]: P } & { [P: string]: Tuple[number] }; - - // Supported Methods - at(n: number): Tuple[number] | undefined; - - // Type override to prevent string not in type T issue - includes(val: PP, fromIndex?: number): boolean; - indexOf(searchElement: PP, fromIndex?: number): number; - lastIndexOf( - searchElement: PP, - fromIndex?: number, - ): number; - - find( - predictate: ( - val: PP extends Tuple[number] & string ? Tuple[number] : PP, - i: number, - obj: Tuple[number][], - ) => val is PP extends Tuple[number] & string ? Tuple[number] : PP, - ): Tuple[number]; - find( - predictate: ( - val: string | undefined, - i: number, - obj: Tuple[number][], - ) => boolean, - ): Tuple[number]; - findIndex( - predicate: ( - value: S & string, - index: number, - obj: Tuple[number][], - ) => unknown, - thisArg?: any, - ): number; - - slice( - start?: Start, - end?: End, - ): [[Start], [End]] extends [[0 | never], [Tuple['length'] | never]] - ? this - : sl.tuple.TupleSlice< - Tuple, - sl.tuple.GetTuplePositiveIndex, - sl.tuple.GetTuplePositiveIndex - > extends infer W extends readonly string[] - ? MaybeReadonly> - : never; - - toSpliced( - start: Start, - ): [Start] extends [0 | never] - ? MaybeReadonly> - : [sl.generic.IsNegative] extends [true] - ? MaybeReadonly> - : sl.tuple.TupleSplit extends readonly [infer C, infer R] - ? C extends readonly string[] - ? R extends readonly string[] - ? MaybeReadonly> - : never + ? MaybeReadonly> + : never; + + withSuffix

( + suffix: P, + ): P extends string + ? StringLiteralList.tuple.TupleSuffixed< + Tuple, + P extends string ? P : '', + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> : never : never; - toSpliced( - start: Start, - deleteCount: DelCount, - ): [ - sl.generic.IsNegative< - sl.generic.Subtract< - sl.generic.Subtract< - Tuple['length'], - [sl.generic.IsNegative] extends [true] ? 0 : Start + // withDerivatedSuffix( + // chars: S, + // ): + // | T + // | StringLiteralList.string.DropSuffix< + // StringLiteralList.string.DropSuffix<`${T}${S}${S}`, S>, + // `${S}${S}` + // > extends infer W extends string + // ? MaybeReadonly> + // : never; + + // withDerivatedPrefix( + // chars: S, + // ): + // | T + // | StringLiteralList.string.DropPrefix< + // StringLiteralList.string.DropPrefix<`${S}${S}${T}`, S>, + // `${S}${S}` + // > extends infer W extends string + // ? MaybeReadonly> + // : never; + + withReplace( + searchValue: S, + replaceValue: D, + ): StringLiteralList.tuple.TupleWithReplace< + Tuple, + S, + D, + [], + false + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + withReplaceAll( + searchValue: S, + replaceValue: D, + ): StringLiteralList.tuple.TupleWithReplace< + Tuple, + S, + D, + [], + true + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + withTrim(): StringLiteralList.tuple.TupleWithTrim< + Tuple, + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + toLowerCase(): StringLiteralList.tuple.TupleWithCaseTransform< + Tuple, + 'lowercase', + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + toUpperCase(): StringLiteralList.tuple.TupleWithCaseTransform< + Tuple, + 'uppercase', + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + toCapitalize(): StringLiteralList.tuple.TupleWithCaseTransform< + Tuple, + 'capitalize', + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + toUnCapitalize(): StringLiteralList.tuple.TupleWithCaseTransform< + Tuple, + 'unCapitalize', + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + value(val): Tuple[number]; + mutable(): (Tuple[number] & string)[]; + sort( + compareFn?: (a: P1, b: P2) => number, + ): MaybeReadonly>; + + reverse(): StringLiteralList.tuple.TupleReversed< + Tuple, + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : this; + + without( + ...arg: readonly (ILiterals | S)[] + ): StringLiteralList.tuple.TupleWithExclude< + Tuple, + S, + [] + > extends infer E extends readonly string[] + ? MaybeReadonly> + : never; + + toSorted( + compareFn?: (a: Tuple[number], b: Tuple[number]) => number, + ): MaybeReadonly>; + + toReversed(): StringLiteralList.tuple.TupleReversed< + Tuple, + [] + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + /** + * @deprecated This method does not support type inference, + * use `list.concat('str', 'str')` or `list.concatList(stringList('str','str'))` instead. + */ + concat( + ...arg: S[] + ): [...Tuple, S[number][number]] extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + concat( + ...arg: S + ): [...Tuple, ...S] extends infer W extends readonly string[] + ? MaybeReadonly< + Mut, + IStringList + > + : never; + + concatList( + arg: ILiterals, + ): S extends infer C extends readonly string[] + ? readonly [...Tuple, ...C] extends infer W extends readonly string[] + ? MaybeReadonly> + : this + : this; + + toRecordType< + RT extends RecordType = 'any', + R extends Record[] = [], + >( + type?: RT, + initial?: RecordTypes[RT], + ...records: R + ): StringLiteralList.record.Merge< + [Record, ...R] + >; + + toRecordValue( + initial?: V, + ...records: R + ): R[number] extends never + ? Record + : StringLiteralList.record.Merge<[Record, ...R]>; + + // Readonly overrides + readonly length: [Unsorted] extends [true] ? number : Tuple['length']; + readonly [n: number]: Tuple[number] | undefined; + readonly enum: { [P in Tuple[number]]: P } & { + [P: string]: Tuple[number]; + }; + + // Supported Methods + at(n: number): Tuple[number] | undefined; + + // Type override to prevent string not in type T issue + includes(val: PP, fromIndex?: number): boolean; + indexOf( + searchElement: PP, + fromIndex?: number, + ): number; + lastIndexOf( + searchElement: PP, + fromIndex?: number, + ): number; + + find( + predictate: ( + val: PP extends Tuple[number] & string ? Tuple[number] : PP, + i: number, + obj: Tuple[number][], + ) => val is PP extends Tuple[number] & string ? Tuple[number] : PP, + ): Tuple[number]; + find( + predictate: ( + val: string | undefined, + i: number, + obj: Tuple[number][], + ) => boolean, + ): Tuple[number]; + findIndex( + predicate: ( + value: S & string, + index: number, + obj: Tuple[number][], + ) => unknown, + thisArg?: any, + ): number; + + slice( + start?: Start, + end?: End, + ): [[Start], [End]] extends [[0 | never], [Tuple['length'] | never]] + ? this + : StringLiteralList.tuple.TupleSlice< + Tuple, + StringLiteralList.tuple.GetTuplePositiveIndex, + StringLiteralList.tuple.GetTuplePositiveIndex + > extends infer W extends readonly string[] + ? MaybeReadonly> + : never; + + toSpliced( + start: Start, + ): [Start] extends [0 | never] + ? MaybeReadonly> + : [StringLiteralList.generic.IsNegative] extends [true] + ? MaybeReadonly> + : StringLiteralList.tuple.TupleSplit extends readonly [ + infer C, + infer R, + ] + ? C extends readonly string[] + ? R extends readonly string[] + ? MaybeReadonly> + : never + : never + : never; + + toSpliced( + start: Start, + deleteCount: DelCount, + ): [ + StringLiteralList.generic.IsNegative< + StringLiteralList.generic.Subtract< + StringLiteralList.generic.Subtract< + Tuple['length'], + [StringLiteralList.generic.IsNegative] extends [true] + ? 0 + : Start + >, + 1 + > >, - 1 - > - >, - ] extends [true] - ? this - : [ - [ - sl.generic.IsNegative< - sl.generic.Subtract< - sl.generic.Subtract< - Tuple['length'], - [DelCount] extends [number] ? DelCount : 0 + ] extends [true] + ? this + : [ + [ + StringLiteralList.generic.IsNegative< + StringLiteralList.generic.Subtract< + StringLiteralList.generic.Subtract< + Tuple['length'], + [DelCount] extends [number] ? DelCount : 0 + >, + 1 + > >, - 1 - > + ], + [Start], + [DelCount], + ] extends + | [[true], [0], [any]] + | [[any], [0], [Tuple['length']]] + | [[any], [0], [never]] + ? MaybeReadonly> + : StringLiteralList.tuple.TupleSplit< + Tuple, + [StringLiteralList.generic.IsNegative] extends [true] + ? 0 + : Start + > extends readonly [infer C, infer R] + ? C extends readonly string[] + ? R extends readonly string[] + ? StringLiteralList.tuple.TupleSplit< + R, + DelCount + > extends readonly [infer D, infer E] + ? E extends readonly string[] + ? MaybeReadonly< + Mut, + IStringList + > + : MaybeReadonly> + : MaybeReadonly> + : never + : never + : never; + + toSpliced< + Start extends number, + DelCount extends number, + I extends string[], + >( + start: Start, + deleteCount: DelCount, + ...items: I + ): [ + StringLiteralList.generic.IsNegative< + StringLiteralList.generic.Subtract< + StringLiteralList.generic.Subtract< + Tuple['length'], + [StringLiteralList.generic.IsNegative] extends [true] + ? 0 + : Start >, - ], - [Start], - [DelCount], - ] extends - | [[true], [0], [any]] - | [[any], [0], [Tuple['length']]] - | [[any], [0], [never]] - ? MaybeReadonly> - : sl.tuple.TupleSplit< - Tuple, - [sl.generic.IsNegative] extends [true] ? 0 : Start - > extends readonly [infer C, infer R] - ? C extends readonly string[] - ? R extends readonly string[] - ? sl.tuple.TupleSplit extends readonly [ - infer D, - infer E, - ] - ? E extends readonly string[] - ? MaybeReadonly< + 1 + > + >, + ] extends [true] + ? readonly [...Tuple, ...I] extends infer W extends readonly string[] + ? MaybeReadonly> + : never + : StringLiteralList.tuple.TupleSplit< + Tuple, + StringLiteralList.tuple.GetTuplePositiveIndex + > extends readonly [infer C, infer R] + ? C extends readonly string[] + ? R extends readonly string[] + ? StringLiteralList.tuple.TupleSplit< + R, + [StringLiteralList.generic.IsNegative] extends [ + true, + ] + ? 0 + : DelCount + > extends readonly [infer D, infer E] + ? E extends readonly string[] + ? MaybeReadonly< + Mut, + IStringList + > + : MaybeReadonly< + Mut, + IStringList + > + : MaybeReadonly< Mut, - IStringList + IStringList > - : MaybeReadonly> - : MaybeReadonly> + : never : never - : never - : never; - - toSpliced( - start: Start, - deleteCount: DelCount, - ...items: I - ): [ - sl.generic.IsNegative< - sl.generic.Subtract< - sl.generic.Subtract< - Tuple['length'], - [sl.generic.IsNegative] extends [true] ? 0 : Start - >, - 1 - > - >, - ] extends [true] - ? readonly [...Tuple, ...I] extends infer W extends readonly string[] - ? MaybeReadonly> - : never - : sl.tuple.TupleSplit< - Tuple, - sl.tuple.GetTuplePositiveIndex - > extends readonly [infer C, infer R] - ? C extends readonly string[] - ? R extends readonly string[] - ? sl.tuple.TupleSplit< - R, - [sl.generic.IsNegative] extends [true] ? 0 : DelCount - > extends readonly [infer D, infer E] - ? E extends readonly string[] - ? MaybeReadonly< - Mut, - IStringList - > - : MaybeReadonly< - Mut, - IStringList - > - : MaybeReadonly< - Mut, - IStringList - > - : never - : never - : never; - - some( - predicate: ( - value: S & string, - index: number, - array: Tuple[number][], - ) => unknown, - thisArg?: any, - ): boolean; - every( - predicate: ( - value: S & string, - index: number, - array: Tuple[number][], - ) => value is S & string, - thisArg?: any, - ): this is S[]; - every( - predicate: ( - value: Tuple[number] & string, - index: number, - array: Tuple[number][], - ) => unknown, - thisArg?: any, - ): boolean; - - // Return Type overrides - /** - * @deprecated This method does not support type inference and will return a mutable T[] array. - */ - with(index: number, value: V): (Tuple[number] | V)[]; - filter( - predicate: ( - value: S & string, - index: number, - array: Tuple[number][], - ) => value is S & string, - thisArg?: any, - ): S[]; - filter( - predicate: ( - value: string, - index: number, - array: Tuple[number][], - ) => boolean, - thisArg?: any, - ): (Tuple[number] & string)[]; - - /** - * @deprecated This method will mutate the list, Get the mutable array with `list.mutable()` - * Or to obtain a modified list without the last element use: - * `const lastElement = list[list.length - 1]` and then remove it using `const newlist = list.without(lastElement)`. - */ - pop(): Tuple[number] | undefined; - - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - * Or use `const firstElement = list[0]` and then remove it using `const newlist = list.without(firstElement)`. - */ - shift(): Tuple[number] | undefined; - - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - * Or use `const newlist = stringList('el', list);`. - */ - unshift(...newElement: S[]): number; - - /** - * @deprecated This method will mutate the list, use `list.concat()` or get the mutable array with `list.mutable()` - */ - push(...items: S[]): number; - - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - * Or to obtain a modified list use: - * `list.toSpliced())`. - */ - splice(start: number, deleteCount?: number): Tuple[number][]; - - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - * Or to obtain a modified list use: - * `list.toSpliced())`. - */ - splice( - start: number, - deleteCount: number, - ...items: Items - ): Tuple[number][]; - - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - */ - copyWithin( - target: number, - start: number, - end?: number, - ): S[]; - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - */ - fill( - value: (U | undefined)[], - start?: number, - end?: number, - ): U[]; - /** - * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` - */ - fill(value: U, start?: number, end?: number): U[]; - join( - delimiter?: D, - ): [this['infered']['TooLong']] extends [true] - ? string - : [Unsorted] extends [true] - ? [Tuple['length']] extends [0] - ? '' - : string - : [Tuple['length']] extends [0] - ? '' - : sl.tuple.TupleSplit extends readonly [ - infer A extends readonly string[], - infer B, - ] - ? B extends readonly string[] - ? `${sl.tuple.Join}` extends infer C extends string - ? C extends '' - ? `${sl.tuple.Join}` - : `${sl.tuple.Join}${D}${C}` - : sl.tuple.Join - : sl.tuple.Join - : string; + : never; + + some( + predicate: ( + value: S & string, + index: number, + array: Tuple[number][], + ) => unknown, + thisArg?: any, + ): boolean; + every( + predicate: ( + value: S & string, + index: number, + array: Tuple[number][], + ) => value is S & string, + thisArg?: any, + ): this is S[]; + every( + predicate: ( + value: Tuple[number] & string, + index: number, + array: Tuple[number][], + ) => unknown, + thisArg?: any, + ): boolean; + + // Return Type overrides + /** + * @deprecated This method does not support type inference and will return a mutable T[] array. + */ + with(index: number, value: V): (Tuple[number] | V)[]; + filter( + predicate: ( + value: S & string, + index: number, + array: Tuple[number][], + ) => value is S & string, + thisArg?: any, + ): S[]; + filter( + predicate: ( + value: string, + index: number, + array: Tuple[number][], + ) => boolean, + thisArg?: any, + ): (Tuple[number] & string)[]; + + /** + * @deprecated This method will mutate the list, Get the mutable array with `list.mutable()` + * Or to obtain a modified list without the last element use: + * `const lastElement = list[list.length - 1]` and then remove it using `const newlist = list.without(lastElement)`. + */ + pop(): Tuple[number] | undefined; + + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + * Or use `const firstElement = list[0]` and then remove it using `const newlist = list.without(firstElement)`. + */ + shift(): Tuple[number] | undefined; + + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + * Or use `const newlist = stringList('el', list);`. + */ + unshift(...newElement: S[]): number; + + /** + * @deprecated This method will mutate the list, use `list.concat()` or get the mutable array with `list.mutable()` + */ + push(...items: S[]): number; + + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + * Or to obtain a modified list use: + * `list.toSpliced())`. + */ + splice(start: number, deleteCount?: number): Tuple[number][]; + + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + * Or to obtain a modified list use: + * `list.toSpliced())`. + */ + splice( + start: number, + deleteCount: number, + ...items: Items + ): Tuple[number][]; + + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + */ + copyWithin( + target: number, + start: number, + end?: number, + ): S[]; + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + */ + fill( + value: (U | undefined)[], + start?: number, + end?: number, + ): U[]; + /** + * @deprecated This method will mutate the list, get the mutable array with `list.mutable()` + */ + fill( + value: U, + start?: number, + end?: number, + ): U[]; + join( + delimiter?: D, + ): [this['infered']['TooLong']] extends [true] + ? string + : [Unsorted] extends [true] + ? [Tuple['length']] extends [0] + ? '' + : string + : [Tuple['length']] extends [0] + ? '' + : StringLiteralList.tuple.TupleSplit extends readonly [ + infer A extends readonly string[], + infer B, + ] + ? B extends readonly string[] + ? `${StringLiteralList.tuple.Join}` extends infer C extends + string + ? C extends '' + ? `${StringLiteralList.tuple.Join}` + : `${StringLiteralList.tuple.Join}${D}${C}` + : StringLiteralList.tuple.Join + : StringLiteralList.tuple.Join + : string; + } + } } - export {}; diff --git a/types/record.d.ts b/types/record.d.ts index 14cb1a4..8e59f17 100644 --- a/types/record.d.ts +++ b/types/record.d.ts @@ -1,22 +1,20 @@ declare global { - export namespace StringLiteralList { - export namespace record { - export type StringRecord = Record< - T, - S - >; + export namespace StringLiteralList {} + export namespace StringLiteralList.record { + export type StringRecord = Record< + T, + S + >; - export type Merge[]> = - Records extends [ - infer A extends Record, - infer B extends Record, - ...infer Rest extends Record[], - ] - ? Merge<[A & Omit, ...Rest]> - : Records extends [infer A] - ? A - : unknown; - } + export type Merge[]> = Records extends [ + infer A extends Record, + infer B extends Record, + ...infer Rest extends Record[], + ] + ? Merge<[A & Omit, ...Rest]> + : Records extends [infer A] + ? A + : unknown; } } diff --git a/types/string.d.ts b/types/string.d.ts index fa45ed0..c021e4c 100644 --- a/types/string.d.ts +++ b/types/string.d.ts @@ -3,143 +3,142 @@ /// declare global { - export namespace StringLiteralList { - export namespace string { - /** - * @credit @gustavoguichard - * For the string manipulation types, - * borrowed and adapted from the library string-ts - */ + export namespace StringLiteralList {} + export namespace StringLiteralList.string { + /** + * @credit @gustavoguichard + * For the string manipulation types, + * borrowed and adapted from the library string-ts + */ - type GetStringPositiveIndex = - generic.IsNegative extends false - ? I - : generic.Subtract, generic.Abs>; + export type GetStringPositiveIndex = + generic.IsNegative extends false + ? I + : generic.Subtract, generic.Abs>; - type IsStringLiteral = [T] extends [string] - ? [string] extends [T] - ? false - : Uppercase extends Uppercase> - ? Lowercase extends Lowercase> - ? true - : false + export type IsStringLiteral = [T] extends [string] + ? [string] extends [T] + ? false + : Uppercase extends Uppercase> + ? Lowercase extends Lowercase> + ? true : false - : false; + : false + : false; - export type Split = - IsStringLiteral extends true - ? T extends `${infer first}${delimiter}${infer rest}` - ? [first, ...Split] - : T extends '' - ? [] - : [T] - : string[]; + export type Split = + IsStringLiteral extends true + ? T extends `${infer first}${delimiter}${infer rest}` + ? [first, ...Split] + : T extends '' + ? [] + : [T] + : string[]; - type Length = - IsStringLiteral extends true ? Split['length'] : number; + export type Length = + IsStringLiteral extends true ? Split['length'] : number; - export type StringConcat< - T1 extends string | number | bigint | boolean, - T2 extends string | number | bigint | boolean, - > = `${T1}${T2}`; + export type StringConcat< + T1 extends string | number | bigint | boolean, + T2 extends string | number | bigint | boolean, + > = `${T1}${T2}`; - type CaseTransform< - T extends string, - Transform extends - | 'uppercase' - | 'lowercase' - | 'capitalize' - | 'unCapitalize', - > = Transform extends 'uppercase' - ? Uppercase - : Transform extends 'lowercase' - ? Lowercase - : Transform extends 'capitalize' + export type CaseTransform< + T extends string, + Transform extends + | 'uppercase' + | 'lowercase' + | 'capitalize' + | 'unCapitalize', + > = Transform extends 'uppercase' + ? Uppercase + : Transform extends 'lowercase' + ? Lowercase + : Transform extends 'capitalize' + ? Split extends [ + infer U extends string, + ...infer Rest extends string[], + ] + ? U extends string + ? [Rest['length']] extends [0] + ? Capitalize + : Rest extends readonly string[] + ? `${Capitalize} ${tuple.Join, ' '>}` + : T + : T + : T + : Transform extends 'unCapitalize' ? Split extends [ infer U extends string, ...infer Rest extends string[], ] ? U extends string ? [Rest['length']] extends [0] - ? Capitalize + ? Uncapitalize : Rest extends readonly string[] - ? `${Capitalize} ${tuple.Join, ' '>}` + ? `${Uncapitalize} ${tuple.Join, ' '>}` : T : T : T - : Transform extends 'unCapitalize' - ? Split extends [ - infer U extends string, - ...infer Rest extends string[], - ] - ? U extends string - ? [Rest['length']] extends [0] - ? Uncapitalize - : Rest extends readonly string[] - ? `${Uncapitalize} ${tuple.Join, ' '>}` - : T - : T - : T - : T; + : T; - export type DropSuffix< - sentence extends string, - suffix extends string, - > = string extends sentence | suffix - ? string - : sentence extends `${infer rest}${suffix}` - ? rest - : sentence; + export type DropSuffix< + sentence extends string, + suffix extends string, + > = string extends sentence | suffix + ? string + : sentence extends `${infer rest}${suffix}` + ? rest + : sentence; - export type DropPrefix< - sentence extends string, - prefix extends string, - > = string extends sentence | prefix - ? string - : sentence extends `${prefix}${infer rest}` - ? rest - : sentence; + export type DropPrefix< + sentence extends string, + prefix extends string, + > = string extends sentence | prefix + ? string + : sentence extends `${prefix}${infer rest}` + ? rest + : sentence; - type TrimStart = - IsStringLiteral extends true - ? T extends ` ${infer rest}` - ? TrimStart - : T - : string; + export type TrimStart = + IsStringLiteral extends true + ? T extends ` ${infer rest}` + ? TrimStart + : T + : string; - type TrimEnd = - IsStringLiteral extends true - ? T extends `${infer rest} ` - ? TrimEnd - : T - : string; + export type TrimEnd = + IsStringLiteral extends true + ? T extends `${infer rest} ` + ? TrimEnd + : T + : string; - export type Trim = TrimEnd>; + export type Trim = TrimEnd>; - export type Replace< - sentence extends string, - lookup extends string | RegExp, - replacement extends string = '', - > = lookup extends string - ? IsStringLiteral extends true - ? sentence extends `${infer rest}${lookup}${infer rest2}` - ? `${rest}${replacement}${rest2}` - : sentence - : string - : string; + export type Replace< + sentence extends string, + lookup extends string | RegExp, + replacement extends string = '', + > = lookup extends string + ? IsStringLiteral extends true + ? sentence extends `${infer rest}${lookup}${infer rest2}` + ? `${rest}${replacement}${rest2}` + : sentence + : string + : string; - type ReplaceAll< - sentence extends string, - lookup extends string | RegExp, - replacement extends string = '', - > = lookup extends string - ? IsStringLiteral extends true - ? sentence extends `${infer rest}${lookup}${infer rest2}` - ? `${rest}${replacement}${ReplaceAll}` - : sentence - : string - : string; - } + export type ReplaceAll< + sentence extends string, + lookup extends string | RegExp, + replacement extends string = '', + > = lookup extends string + ? IsStringLiteral extends true + ? sentence extends `${infer rest}${lookup}${infer rest2}` + ? `${rest}${replacement}${ReplaceAll}` + : sentence + : string + : string; } } diff --git a/types/tuple.d.ts b/types/tuple.d.ts index c70b660..ff659ce 100644 --- a/types/tuple.d.ts +++ b/types/tuple.d.ts @@ -3,282 +3,281 @@ /// declare global { - export namespace StringLiteralList { + export namespace StringLiteralList {} + /** + * @name tuple + * @description A tuple is a an immutable list of elements that infer the position and the length of its elements. + * This is useful to create an array that is used as an argument for a function that requires an ordered list of parameters. + */ + export namespace StringLiteralList.tuple { + export type GetTuplePositiveIndex< + T extends readonly any[], + I extends number, + > = + generic.IsNegative extends false + ? I + : generic.Subtract>; + + export type IsStringLiteralArray = + string.IsStringLiteral extends true ? true : false; /** - * @name tuple - * @description A tuple is a an immutable list of elements that infer the position and the length of its elements. - * This is useful to create an array that is used as an argument for a function that requires an ordered list of parameters. + * Takes a union of strings and returns a tuple of them. + * @deprecated this doesn't infer the length and the position of the tuple. It will also drop duplicates. */ - export namespace tuple { - export type GetTuplePositiveIndex< - T extends readonly any[], - I extends number, - > = - generic.IsNegative extends false - ? I - : generic.Subtract>; - - type IsStringLiteralArray = - string.IsStringLiteral extends true ? true : false; - /** - * Takes a union of strings and returns a tuple of them. - * @deprecated this doesn't infer the length and the position of the tuple. It will also drop duplicates. - */ - export type UnionToTuple = - generic.UnionToIntersection< - T extends never ? never : T extends string ? (t: T) => T : never - > extends (_: never) => infer W - ? W extends string - ? readonly [...UnionToTuple>, W] - : never - : readonly []; + export type UnionToTuple = + generic.UnionToIntersection< + T extends never ? never : T extends string ? (t: T) => T : never + > extends (_: never) => infer W + ? W extends string + ? readonly [...UnionToTuple>, W] + : never + : readonly []; - export type TupleSplit< - T, - N extends number, - O extends readonly any[] = readonly [], - > = O['length'] extends N - ? [O, T] - : T extends readonly [infer F, ...infer R] - ? TupleSplit - : [O, T]; + export type TupleSplit< + T, + N extends number, + O extends readonly any[] = readonly [], + > = O['length'] extends N + ? [O, T] + : T extends readonly [infer F, ...infer R] + ? TupleSplit + : [O, T]; - type TupleExplode = T extends readonly [ - infer Head, - ...infer Rest, - ] - ? Head extends readonly [] - ? Exploded - : Rest extends readonly [] - ? [...Exploded, readonly [Head]] - : TupleExplode - : Exploded; + export type TupleExplode< + T, + Exploded extends any[] = [], + > = T extends readonly [infer Head, ...infer Rest] + ? Head extends readonly [] + ? Exploded + : Rest extends readonly [] + ? [...Exploded, readonly [Head]] + : TupleExplode + : Exploded; - type TupleImplode< - T, - Imploded extends readonly any[] = readonly [], - > = T extends readonly [infer Head, ...infer Rest] - ? Head extends readonly [] - ? Imploded - : Head extends readonly [...infer Head] - ? Rest extends readonly [] - ? readonly [...Imploded, ...Head] - : TupleImplode - : Imploded - : Imploded; + export type TupleImplode< + T, + Imploded extends readonly any[] = readonly [], + > = T extends readonly [infer Head, ...infer Rest] + ? Head extends readonly [] + ? Imploded + : Head extends readonly [...infer Head] + ? Rest extends readonly [] + ? readonly [...Imploded, ...Head] + : TupleImplode + : Imploded + : Imploded; - type TakeFirst = TupleSplit< - T, - N - >[0]; + export type TakeFirst< + T extends readonly any[], + N extends number, + > = TupleSplit[0]; - type SkipFirst = TupleSplit< - T, - N - >[1]; + export type SkipFirst< + T extends readonly any[], + N extends number, + > = TupleSplit[1]; - type TupleSlice< - T extends readonly any[], - S extends number, - E extends number, - > = SkipFirst, S>; + export type TupleSlice< + T extends readonly any[], + S extends number, + E extends number, + > = SkipFirst, S>; - export type TuplePrefixed< - T extends readonly string[], - P extends string, - Transformed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TuplePrefixed - : readonly [...Transformed, `${P}${H}`] - : Transformed - : Transformed; + export type TuplePrefixed< + T extends readonly string[], + P extends string, + Transformed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TuplePrefixed + : readonly [...Transformed, `${P}${H}`] + : Transformed + : Transformed; - export type TupleSuffixed< - T extends readonly string[], - S extends string, - Transformed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TupleSuffixed - : readonly [...Transformed, `${H}${S}`] - : Transformed - : Transformed; + export type TupleSuffixed< + T extends readonly string[], + S extends string, + Transformed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TupleSuffixed + : readonly [...Transformed, `${H}${S}`] + : Transformed + : Transformed; - export type TupleWithReplace< - T extends readonly string[], - Lookup extends string | RegExp, - Replacement extends string, - Transformed extends readonly string[], - All extends boolean = false, - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TupleWithReplace< - R, - Lookup, - Replacement, - readonly [ - ...Transformed, - [All] extends [false] - ? string.Replace - : string.ReplaceAll, - ], - All - > - : readonly [ + export type TupleWithReplace< + T extends readonly string[], + Lookup extends string | RegExp, + Replacement extends string, + Transformed extends readonly string[], + All extends boolean = false, + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TupleWithReplace< + R, + Lookup, + Replacement, + readonly [ ...Transformed, [All] extends [false] ? string.Replace : string.ReplaceAll, - ] - : Transformed - : Transformed; + ], + All + > + : readonly [ + ...Transformed, + [All] extends [false] + ? string.Replace + : string.ReplaceAll, + ] + : Transformed + : Transformed; - export type TupleWithCaseTransform< - T extends readonly string[], - Transform extends - | 'uppercase' - | 'lowercase' - | 'capitalize' - | 'unCapitalize', - Transformed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TupleWithCaseTransform< - R, - Transform, - readonly [...Transformed, string.CaseTransform] - > - : readonly [...Transformed, string.CaseTransform] - : Transformed - : Transformed; + export type TupleWithCaseTransform< + T extends readonly string[], + Transform extends + | 'uppercase' + | 'lowercase' + | 'capitalize' + | 'unCapitalize', + Transformed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TupleWithCaseTransform< + R, + Transform, + readonly [...Transformed, string.CaseTransform] + > + : readonly [...Transformed, string.CaseTransform] + : Transformed + : Transformed; - export type TupleWithTrim< - T extends readonly string[], - Transformed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TupleWithTrim]> - : readonly [...Transformed, string.Trim] - : Transformed - : Transformed; + export type TupleWithTrim< + T extends readonly string[], + Transformed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TupleWithTrim]> + : readonly [...Transformed, string.Trim] + : Transformed + : Transformed; - export type TupleWithExclude< - T extends readonly string[], - E extends string, - Transformed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? TupleWithExclude< - R, - E, - [H] extends [E] ? Transformed : readonly [...Transformed, H] - > - : [H] extends [E] - ? Transformed - : readonly [...Transformed, H] - : Transformed - : Transformed; + export type TupleWithExclude< + T extends readonly string[], + E extends string, + Transformed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? TupleWithExclude< + R, + E, + [H] extends [E] ? Transformed : readonly [...Transformed, H] + > + : [H] extends [E] + ? Transformed + : readonly [...Transformed, H] + : Transformed + : Transformed; - export type TupleReversed< - T extends readonly string[], - Reversed extends readonly string[], - > = T extends readonly [infer H, ...infer R] - ? H extends string - ? R extends readonly string[] - ? Reversed extends readonly string[] - ? TupleReversed - : readonly [H, ...R] - : readonly [H] - : Reversed - : Reversed; + export type TupleReversed< + T extends readonly string[], + Reversed extends readonly string[], + > = T extends readonly [infer H, ...infer R] + ? H extends string + ? R extends readonly string[] + ? Reversed extends readonly string[] + ? TupleReversed + : readonly [H, ...R] + : readonly [H] + : Reversed + : Reversed; - type JoinInner< - T extends readonly string[], - delimiter extends string = '', - > = T extends readonly [ - infer first extends string, - ...infer rest extends readonly string[], - ] - ? rest extends [] - ? first - : `${first}${delimiter}${JoinInner}` - : ''; + export type JoinInner< + T extends readonly string[], + delimiter extends string = '', + > = T extends readonly [ + infer first extends string, + ...infer rest extends readonly string[], + ] + ? rest extends [] + ? first + : `${first}${delimiter}${JoinInner}` + : ''; - export type Join< - T extends readonly string[], - delimiter extends string = '', - > = delimiter extends string - ? T extends readonly string[] - ? TupleSplit extends [ - infer L extends readonly string[], - infer R extends readonly string[], - ] - ? JoinInner extends infer C extends string - ? `${R['length']}` extends `0` - ? C - : R extends readonly string[] - ? string.Length<`${R['length']}`> extends 1 | 2 - ? JoinInner extends infer D extends string - ? `${C}${D}` - : Join - : '' + export type Join< + T extends readonly string[], + delimiter extends string = '', + > = delimiter extends string + ? T extends readonly string[] + ? TupleSplit extends [ + infer L extends readonly string[], + infer R extends readonly string[], + ] + ? JoinInner extends infer C extends string + ? `${R['length']}` extends `0` + ? C + : R extends readonly string[] + ? string.Length<`${R['length']}`> extends 1 | 2 + ? JoinInner extends infer D extends string + ? `${C}${D}` + : Join : '' - : '' + : '' : '' - : never - : never; + : '' + : never + : never; - export type TupleJoin< - T extends readonly string[], - Joined extends readonly string[], - > = T extends readonly [infer A, ...infer Rest] - ? A extends { infered: { Tuple: readonly string[] } } - ? Rest extends readonly [] - ? readonly [...Joined, ...A['infered']['Tuple']] - : Rest extends readonly { infered: { Tuple: readonly string[] } }[] - ? ILiteralsTupleJoin - : Joined - : [] - : []; + export type TupleJoin< + T extends readonly string[], + Joined extends readonly string[], + > = T extends readonly [infer A, ...infer Rest] + ? A extends { infered: { Tuple: readonly string[] } } + ? Rest extends readonly [] + ? readonly [...Joined, ...A['infered']['Tuple']] + : Rest extends readonly { infered: { Tuple: readonly string[] } }[] + ? ILiteralsTupleJoin + : Joined + : [] + : []; - export type ILiteralsTupleJoin< - T extends readonly Partial<{ - infered: Partial<{ Tuple: readonly unknown[] }>; - }>[], - Joined extends readonly string[], - > = T extends readonly [infer A, ...infer Rest] - ? A extends Partial<{ infered: Partial<{ Tuple: readonly string[] }> }> - ? Rest extends [] - ? A['infered']['Tuple'] extends infer L extends readonly string[] - ? readonly [...Joined, ...L] - : never - : Rest extends readonly Partial<{ - infered: Partial<{ Tuple: readonly unknown[] }>; - }>[] - ? A['infered']['Tuple'] extends infer L extends readonly string[] - ? ILiteralsTupleJoin - : never - : Joined - : A extends Partial<{ - infered: Partial<{ Tuple: readonly string[] }>; - }> + export type ILiteralsTupleJoin< + T extends readonly Partial<{ + infered: Partial<{ Tuple: readonly unknown[] }>; + }>[], + Joined extends readonly string[], + > = T extends readonly [infer A, ...infer Rest] + ? A extends Partial<{ infered: Partial<{ Tuple: readonly string[] }> }> + ? Rest extends [] + ? A['infered']['Tuple'] extends infer L extends readonly string[] + ? readonly [...Joined, ...L] + : never + : Rest extends readonly Partial<{ + infered: Partial<{ Tuple: readonly unknown[] }>; + }>[] ? A['infered']['Tuple'] extends infer L extends readonly string[] - ? [...Joined, ...A['infered']['Tuple']] + ? ILiteralsTupleJoin : never - : Rest extends readonly Partial<{ - infered: Partial<{ Tuple: readonly unknown[] }>; - }>[] - ? ILiteralsTupleJoin - : Joined - : Joined; - } + : Joined + : A extends Partial<{ + infered: Partial<{ Tuple: readonly string[] }>; + }> + ? A['infered']['Tuple'] extends infer L extends readonly string[] + ? [...Joined, ...A['infered']['Tuple']] + : never + : Rest extends readonly Partial<{ + infered: Partial<{ Tuple: readonly unknown[] }>; + }>[] + ? ILiteralsTupleJoin + : Joined + : Joined; } }