UNPKG

@plugjs/plug

Version:
55 lines (45 loc) 2.4 kB
/** A type extacting string parameters from an arguments array */ export type ParsedParams<Args extends readonly any[]> = // Normal tuple, we stop processing if the _first_ argument is not a string! Args extends readonly [ infer First, ...infer Rest ] ? First extends string ? [ First, ...ParsedParams<Rest> ] : [] : // If not caught above, here "first" is the rest parameter in the tuple Args extends readonly [ ...infer First, infer Rest ] ? Rest extends string ? [ ...ParsedParams<First>, Rest ] : [ ...ParsedParams<First> ] : // Not a tuple: normal string array or the end of our arguments Args extends readonly string[] ? [ ...Args ] : [] /** A type extacting the (last) options type from an arguments array */ export type ParsedOptions<Args extends readonly any[]> = // , Defaults> = Args extends readonly [ ...string[], infer Last ] ? Last extends object ? // Record<any, any> ? Last : // last arg is a record, defaults is null or undefined never : // last arg is a string, defaults is null or undefined never // args is not an array /** Parserable arguments: a number of strings, followed by optional options */ export type ParseOptions<Options extends Record<any, any>> = readonly [ ...params: string[] ] | readonly [ ...params: string[], options: Options ] /** The return type from {@link ParseOptions} */ export interface ParsedResult<Args extends readonly any [], Options, Defaults> { params: ParsedParams<Args>, options: Defaults extends null | undefined ? Options | undefined : Options & Defaults } /** * Parse an array of arguments (a number of strings optionally followed by an * options object into parameters and options. */ export function parseOptions< Args extends ParseOptions<any>, Options extends ParsedOptions<Args> = ParsedOptions<Args>, Defaults extends ParsedOptions<Args> | null | undefined = undefined, >(args: Args, defaults?: Defaults): ParsedResult<Args, Options, Defaults> { const params: string[] = [] const clone: any[] = [ ...args ] // Collect all strings at the beginning of our arguments array while (typeof clone[0] === 'string') { params.push(clone.shift()) } // The options is the _last_ element in our arguments array (if any) const options = Object.assign({}, defaults, clone.pop()) // All done return { params, options } as ParsedResult<Args, Options, Defaults> }