diff --git a/index.d.ts b/index.d.ts index e92d14a..75ceae5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -25,7 +25,8 @@ declare namespace meow { type BooleanFlag = Flag<'boolean', boolean>; type NumberFlag = Flag<'number', number>; - type AnyFlags = {[key: string]: StringFlag | BooleanFlag | NumberFlag}; + type AnyFlag = StringFlag | BooleanFlag | NumberFlag; + type AnyFlags = {[key: string]: AnyFlag}; interface Options { /** @@ -195,14 +196,26 @@ declare namespace meow { readonly hardRejection?: boolean; } - type TypedFlags = { - [F in keyof Flags]: Flags[F] extends {type: 'number'} + type TypedFlag = + Flag extends {type: 'number'} ? number - : Flags[F] extends {type: 'string'} + : Flag extends {type: 'string'} ? string - : Flags[F] extends {type: 'boolean'} + : Flag extends {type: 'boolean'} ? boolean : unknown; + + type PossiblyOptionalFlag = + Flag extends {isRequired: true} + ? FlagType + : Flag extends {default: any} + ? FlagType + : FlagType | undefined; + + type TypedFlags = { + [F in keyof Flags]: Flags[F] extends {isMultiple: true} + ? PossiblyOptionalFlag>> + : PossiblyOptionalFlag> }; interface Result { diff --git a/index.test-d.ts b/index.test-d.ts index 640b8ca..c3003e8 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -6,12 +6,21 @@ import {Result} from '.'; expectType>(meow('Help text')); expectType>(meow('Help text', {hardRejection: false})); expectAssignable<{flags: {foo: number}}>( - meow({flags: {foo: {type: 'number'}}}) + meow({flags: {foo: {type: 'number', isRequired: true}}}) ); expectAssignable<{flags: {foo: string}}>( - meow({flags: {foo: {type: 'string'}}}) + meow({flags: {foo: {type: 'string', isRequired: true}}}) ); expectAssignable<{flags: {foo: boolean}}>( + meow({flags: {foo: {type: 'boolean', isRequired: true}}}) +); +expectAssignable<{flags: {foo: number | undefined}}>( + meow({flags: {foo: {type: 'number'}}}) +); +expectAssignable<{flags: {foo: string | undefined}}>( + meow({flags: {foo: {type: 'string'}}}) +); +expectAssignable<{flags: {foo: boolean | undefined}}>( meow({flags: {foo: {type: 'boolean'}}}) ); expectType>(meow({description: 'foo'})); @@ -34,7 +43,8 @@ const result = meow('Help text', { flags: { foo: {type: 'boolean', alias: 'f'}, 'foo-bar': {type: 'number'}, - bar: {type: 'string', default: ''} + bar: {type: 'string', default: ''}, + abc: {type: 'string', isMultiple: true} } }); @@ -42,13 +52,15 @@ expectType(result.input); expectType(result.pkg); expectType(result.help); -expectType(result.flags.foo); +expectType(result.flags.foo); expectType(result.flags.fooBar); expectType(result.flags.bar); -expectType(result.unnormalizedFlags.foo); +expectType(result.flags.abc); +expectType(result.unnormalizedFlags.foo); expectType(result.unnormalizedFlags.f); -expectType(result.unnormalizedFlags['foo-bar']); +expectType(result.unnormalizedFlags['foo-bar']); expectType(result.unnormalizedFlags.bar); +expectType(result.unnormalizedFlags.abc); result.showHelp(); result.showHelp(1); diff --git a/test/test.js b/test/test.js index 44e34a0..e1f329a 100644 --- a/test/test.js +++ b/test/test.js @@ -510,6 +510,17 @@ test('isMultiple - handles multi-word flag name', t => { }); }); +test('isMultiple - handles non-set flags correctly', t => { + t.deepEqual(meow({ + argv: [], + flags: { + foo: { + isMultiple: true + } + } + }).flags, {}); +}); + if (NODE_MAJOR_VERSION >= 14) { test('supports es modules', async t => { try { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..720afed --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "files": [ + "index.d.ts", + "index.test-d.ts", + ], + "compilerOptions": { + "strict": true, + "jsx": "react", + "target": "es2018", + "lib": [ + "es2018" + ], + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "strictNullChecks": true, + "noUnusedLocals": true + } +}