UNPKG

@data-client/rest

Version:

Quickly define typed REST resources and endpoints

57 lines (48 loc) 1.85 kB
type OnlyOptional<S extends string> = S extends `${infer K}}?` ? K : S extends `${infer K}?` ? K : never; type OnlyRequired<S extends string> = S extends `${string}?` ? never : S; /** Parameters for a given path */ export type PathArgs<S extends string> = PathKeys<S> extends never ? // unknown is identity for intersection ('&') unknown : KeysToArgs<PathKeys<S>>; /** Computes the union of keys for a path string */ export type PathKeys<S extends string> = string extends S ? string : S extends `${infer A}\\${':' | '?' | '+' | '*' | '{' | '}'}${infer B}` ? PathKeys<A> | PathKeys<B> : PathSplits<S>; type PathSplits<S extends string> = S extends ( `${string}:${infer K}${'/' | ',' | '%' | '&' | '+' | '*' | '{'}${infer R}` ) ? PathSplits<`:${K}`> | PathSplits<R> : S extends `${string}:${infer K}:${infer R}` ? PathSplits<`:${K}`> | PathSplits<`:${R}`> : S extends `${string}:${infer K}` ? K : never; export type KeysToArgs<Key extends string> = { [K in Key as OnlyOptional<K>]?: string | number; } & (OnlyRequired<Key> extends never ? unknown : { [K in Key as OnlyRequired<K>]: string | number; }); export type PathArgsAndSearch<S extends string> = OnlyRequired<PathKeys<S>> extends never ? Record<string, number | string | boolean> | undefined : { [K in PathKeys<S> as OnlyRequired<K>]: string | number; } & Record<string, number | string>; /** Removes the last :token */ export type ShortenPath<S extends string> = string extends S ? string : S extends `${infer B}:${infer R}` ? TrimColon<`${B}:${ShortenPath<R>}`> : ''; type TrimColon<S extends string> = string extends S ? string : S extends `${infer R}:` ? R : S; export type ResourcePath = string; // `${string}:${string}`; TODO: Maybe do this in the future? Seems to hard to understand for now