From e7bdc117ee851868345ff771b9879db8107a969b Mon Sep 17 00:00:00 2001 From: Joram van den Boezem Date: Wed, 27 May 2020 22:15:18 +0000 Subject: [PATCH] feat: prefer choices --- examples/types.ts | 39 +++++++++++++++++++++++++++++++++------ src/baseArg.ts | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/examples/types.ts b/examples/types.ts index 614ae3af..086c9893 100644 --- a/examples/types.ts +++ b/examples/types.ts @@ -1,20 +1,47 @@ import { program, command } from '../src' +/** + * Keep in mind that argument/option types are not validated at runtime. + * For example, when providing a default value with type boolean, it can be set + * to a string value at runtime. + */ + const string = command('string') - .argument('arg', 'Required string argument') - .option('opt', 'Optional string option', { type: 'string' }) + .argument('arg', { description: 'Required string argument' }) + .option('opt', { description: 'Optional string option', type: 'string' }) .action((args) => { console.log('Args are', args) }) -const choices = command('string') - .argument('arg', 'Required string argument') - .option('opt', 'Optional string option', { type: 'string' }) +const choices = command('choices') + .argument('arg', { + description: 'Argument with choices', + choices: ['foo', 'bar'] as const, + }) + .option('opt', { + description: 'Option with choices', + choices: ['option1', 'option2'] as const, + default: 'option3', + }) .action((args) => { console.log('Args are', args) }) +const defaultValues = command('default') + .argument('arg', { + description: 'Optional argument with default value', + default: 5, + optional: true, + }) + .option('opt', { description: 'Default value', default: true }) + .action((args) => { + console.log('Args are', args) + }) -const app = program().description('All argument and option types').add(string) +const app = program() + .description('All argument and option types') + .add(string) + .add(choices) + .add(defaultValues) app.withHelp().runOrRepl() diff --git a/src/baseArg.ts b/src/baseArg.ts index 5c91cd26..b69fb73e 100644 --- a/src/baseArg.ts +++ b/src/baseArg.ts @@ -6,21 +6,33 @@ export interface BaseArgOptions { prompt?: true | string } -export type InferArgType< - O extends Options | PositionalOptions, - D = unknown -> = O extends { - variadic: true - type: 'number' -} // Add support for numeric variadic arguments - ? Array - : O extends { - variadic: true - } // Add support for string variadic arguments - ? Array - : unknown extends InferredOptionType // Allow default type - ? D - : InferredOptionType +export type InferArgType = + /** + * Add support for numeric variadic arguments + */ + O extends { + variadic: true + type: 'number' + } + ? Array + : /** + * Add support for string variadic arguments + */ + O extends { + variadic: true + } + ? Array + : /** + * Prefer choices over default + */ + O extends { choices: ReadonlyArray } + ? C + : /** + * Allow fallback type + */ + unknown extends InferredOptionType + ? F + : InferredOptionType export class BaseArg { protected name: string