/** * Utility types for TypeScript. Use this module by importing from * `@sirpepe/shed/types`. */ /** * Splits a tuple type into a LHS and a RHS on index `I` */ export type SplitTuple = L["length"] extends I ? [L, R] : R extends [infer First, ...infer Rest] ? SplitTuple<[...Rest], I, [...L, First]> : [L, R]; /** * Drops the first element from a tuple type. */ export type DropFirst = T extends [any, ...infer Rest] ? Rest : T; /** * Drops the element at index `I` from a tuple type. */ export type Drop = [ ...SplitTuple[0], ...DropFirst[1]> ]; /** * This vile concoction creates an index type that maps the members of * union `U` by their discriminant `K` with `MapDiscriminatedUnion` */ type DiscriminateUnion = Union extends Record ? Union : never; export type MapDiscriminatedUnion, Key extends keyof Union> = { [Value in Union[Key]]: DiscriminateUnion; }; /** * Makes select keys on `Source` optional */ export type Optional = { [Key in Keys]?: Source[Key]; } & Pick>; /** * Makes select keys on `Source` required */ export type NonOptional = { [Key in Keys]-?: Source[Key]; } & Pick>; type SplitPath = Path extends `${infer First}.${infer Rest}` ? SplitPath : [...Segments, Path]; type QuerySegments = Segments extends [] ? T : Segments[0] extends keyof T ? QuerySegments> : unknown; /** * Returns the type of a nested object member */ export type QueryPath = QuerySegments>; type Whitespace = " " | "\n"; type TrimLeft = T extends `${Whitespace}${infer Rest}` ? TrimLeft : T; type TrimRight = T extends `${infer Rest}${Whitespace}` ? TrimRight : T; export type Trim = TrimLeft>; export type Split = Str extends any ? Trim extends `${infer First}${Whitespace}${infer Rest}` ? Split | Last> : Trim | Last : never; export type Primitive = string | boolean | number | undefined | null | symbol | bigint; export {};