From cf10ef4744f49f4f0565c167dd754c664992718b Mon Sep 17 00:00:00 2001 From: Alexander Kireev Date: Fri, 19 Jun 2026 16:29:00 +0700 Subject: [PATCH] fix: array type flags (number/boolean/string) now respect their value When an array option was configured with an object such as { key: 'foo', number: false }, the parser enabled number coercion regardless of the value because it only checked for the presence of the key rather than whether it was truthy. As a result, number: false, number: undefined, boolean: false and string: false all changed parsing instead of being treated as if the flag were absent. Only enable the corresponding coercion when the type flag is === true. Closes #415 --- lib/yargs-parser.ts | 19 +++++++++++-------- test/yargs-parser.mjs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/lib/yargs-parser.ts b/lib/yargs-parser.ts index 48a2d0f2..9c16b6d9 100644 --- a/lib/yargs-parser.ts +++ b/lib/yargs-parser.ts @@ -115,14 +115,17 @@ export class YargsParser { const key = typeof opt === 'object' ? opt.key : opt // assign to flags[bools|strings|numbers] - const assignment: ArrayFlagsKey | undefined = Object.keys(opt).map(function (key) { - const arrayFlagKeys: Record = { - boolean: 'bools', - string: 'strings', - number: 'numbers' - } - return arrayFlagKeys[key] - }).filter(Boolean).pop() + const arrayFlagKeys: Record = { + boolean: 'bools', + string: 'strings', + number: 'numbers' + } + const assignment: ArrayFlagsKey | undefined = typeof opt === 'object' + ? Object.keys(arrayFlagKeys) + .filter((flagKey) => (opt as Record)[flagKey] === true) + .map((flagKey) => arrayFlagKeys[flagKey]) + .pop() + : undefined // assign key to be coerced if (assignment) { diff --git a/test/yargs-parser.mjs b/test/yargs-parser.mjs index 4c692375..f5f422a7 100644 --- a/test/yargs-parser.mjs +++ b/test/yargs-parser.mjs @@ -1877,6 +1877,37 @@ describe('yargs-parser', function () { result.should.have.property('x').that.is.an('array').and.to.deep.equal(['5', '2']) }) + // see https://github.com/yargs/yargs-parser/issues/415 + // a falsy type flag should be treated as if it were absent, rather than + // enabling the corresponding coercion. + it('should not coerce array values to number when `number` is false', function () { + const result = parser(['--foo', 'dog', 'cat'], { + array: [{ key: 'foo', number: false }] + }) + result.should.have.property('foo').that.is.an('array').and.to.deep.equal(['dog', 'cat']) + }) + + it('should not coerce array values to number when `number` is undefined', function () { + const result = parser(['--foo', 'dog', 'cat'], { + array: [{ key: 'foo', number: undefined }] + }) + result.should.have.property('foo').that.is.an('array').and.to.deep.equal(['dog', 'cat']) + }) + + it('should not coerce array values to boolean when `boolean` is false', function () { + const result = parser(['--foo', 'dog', 'cat'], { + array: [{ key: 'foo', boolean: false }] + }) + result.should.have.property('foo').that.is.an('array').and.to.deep.equal(['dog', 'cat']) + }) + + it('should not coerce array values to string when `string` is false', function () { + const result = parser(['--foo', '1', '2'], { + array: [{ key: 'foo', string: false }] + }) + result.should.have.property('foo').that.is.an('array').and.to.deep.equal([1, 2]) + }) + it('should eat non-hyphenated arguments until hyphenated option is hit - combined with coercion', function () { const result = parser([ '-a=hello', 'world',