From 07159799c1ebc7ff9a6e6d0060c0ea64c8584a16 Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Thu, 18 Jun 2020 12:24:47 +0200 Subject: [PATCH 1/6] Add tsconfig.json that indicates ts config Without this something like VS Code can't understand what the actual config is, even if tsd itself will know --- tsconfig.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tsconfig.json diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8a5db7b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "files": [ + "index.d.ts", + "index.test-d.ts", + ], + "compilerOptions": { + "strict": true, + "jsx": "react", + "target": "es2017", + "lib": ["es2017"], + "module": "commonjs", + "moduleResolution": "node", + + /* Strict Type-Checking Options */ + "noImplicitAny": true, + "strictNullChecks": true, + + /* Additional Checks */ + "noUnusedLocals": true + } +} From 632566a30a7c5f47e5b2ded3080c4bec398f1d2d Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Thu, 18 Jun 2020 13:14:48 +0200 Subject: [PATCH 2/6] Flag types support for isRequired and isMultiple --- index.d.ts | 23 ++++++++++++++++++----- index.test-d.ts | 24 ++++++++++++++++++------ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/index.d.ts b/index.d.ts index e92d14a..6366dfb 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} + ? TypedFlag + : Flag extends {default: any} + ? TypedFlag + : TypedFlag|undefined; + + type TypedFlags = { + [F in keyof Flags]: Flags[F] extends {isMultiple: true} + ? Array> + : PossiblyOptionalFlag }; interface Result { diff --git a/index.test-d.ts b/index.test-d.ts index 640b8ca..7c81b86 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); From 6a9e795ec3fef7157f7e866f33f193539597d064 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Jul 2020 04:32:59 +0800 Subject: [PATCH 3/6] Update index.test-d.ts --- index.test-d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/index.test-d.ts b/index.test-d.ts index 7c81b86..f778c92 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -14,13 +14,13 @@ expectAssignable<{flags: {foo: string}}>( expectAssignable<{flags: {foo: boolean}}>( meow({flags: {foo: {type: 'boolean', isRequired: true}}}) ); -expectAssignable<{flags: {foo: number|undefined}}>( +expectAssignable<{flags: {foo: number | undefined}}>( meow({flags: {foo: {type: 'number'}}}) ); -expectAssignable<{flags: {foo: string|undefined}}>( +expectAssignable<{flags: {foo: string | undefined}}>( meow({flags: {foo: {type: 'string'}}}) ); -expectAssignable<{flags: {foo: boolean|undefined}}>( +expectAssignable<{flags: {foo: boolean | undefined}}>( meow({flags: {foo: {type: 'boolean'}}}) ); expectType>(meow({description: 'foo'})); @@ -52,13 +52,13 @@ 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.flags.abc); -expectType(result.unnormalizedFlags.foo); +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); From f26f8310764edfa2cbbcd40c7f107e2dc5e81ada Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Jul 2020 04:34:23 +0800 Subject: [PATCH 4/6] Update tsconfig.json --- tsconfig.json | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 8a5db7b..720afed 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,19 @@ { - "files": [ - "index.d.ts", - "index.test-d.ts", - ], - "compilerOptions": { - "strict": true, - "jsx": "react", - "target": "es2017", - "lib": ["es2017"], - "module": "commonjs", - "moduleResolution": "node", - - /* Strict Type-Checking Options */ - "noImplicitAny": true, - "strictNullChecks": true, - - /* Additional Checks */ - "noUnusedLocals": true - } + "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 + } } From 93d23f146f39041469d00749f753d0554f1b03ca Mon Sep 17 00:00:00 2001 From: Pelle Wessman Date: Mon, 10 Aug 2020 22:08:00 +0200 Subject: [PATCH 5/6] Add tests for undefined isMultiple + fix types --- index.d.ts | 12 ++++++------ index.test-d.ts | 4 ++-- test/test.js | 11 +++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/index.d.ts b/index.d.ts index 6366dfb..7215215 100644 --- a/index.d.ts +++ b/index.d.ts @@ -205,17 +205,17 @@ declare namespace meow { ? boolean : unknown; - type PossiblyOptionalFlag = + type PossiblyOptionalFlag = Flag extends {isRequired: true} - ? TypedFlag + ? FlagType : Flag extends {default: any} - ? TypedFlag - : TypedFlag|undefined; + ? FlagType + : FlagType|undefined; type TypedFlags = { [F in keyof Flags]: Flags[F] extends {isMultiple: true} - ? Array> - : PossiblyOptionalFlag + ? PossiblyOptionalFlag>> + : PossiblyOptionalFlag> }; interface Result { diff --git a/index.test-d.ts b/index.test-d.ts index f778c92..c3003e8 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -55,12 +55,12 @@ expectType(result.help); expectType(result.flags.foo); expectType(result.flags.fooBar); expectType(result.flags.bar); -expectType(result.flags.abc); +expectType(result.flags.abc); expectType(result.unnormalizedFlags.foo); expectType(result.unnormalizedFlags.f); expectType(result.unnormalizedFlags['foo-bar']); expectType(result.unnormalizedFlags.bar); -expectType(result.unnormalizedFlags.abc); +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 { From e6d9dfb938ef7aa81f6a1cf965d9046967f4174f Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 10 Aug 2020 22:21:05 +0200 Subject: [PATCH 6/6] Update index.d.ts --- index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 7215215..75ceae5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -25,7 +25,7 @@ declare namespace meow { type BooleanFlag = Flag<'boolean', boolean>; type NumberFlag = Flag<'number', number>; - type AnyFlag = StringFlag | BooleanFlag | NumberFlag; + type AnyFlag = StringFlag | BooleanFlag | NumberFlag; type AnyFlags = {[key: string]: AnyFlag}; interface Options { @@ -210,7 +210,7 @@ declare namespace meow { ? FlagType : Flag extends {default: any} ? FlagType - : FlagType|undefined; + : FlagType | undefined; type TypedFlags = { [F in keyof Flags]: Flags[F] extends {isMultiple: true}