Skip to content

fix: array sub-type option respects its value, not just its presence (#415)#536

Closed
simonkundrik wants to merge 1 commit into
yargs:mainfrom
simonkundrik:fix/array-subtype-respects-value
Closed

fix: array sub-type option respects its value, not just its presence (#415)#536
simonkundrik wants to merge 1 commit into
yargs:mainfrom
simonkundrik:fix/array-subtype-respects-value

Conversation

@simonkundrik

Copy link
Copy Markdown

Fixes #415

An array option configured with a falsy sub-type flag still enabled that coercion. For example, { key: 'foo', number: false } coerced the array values as numbers:

const parser = require('yargs-parser')

parser('--foo dog cat', { array: { key: 'foo', number: false } })
// before: { _: [], foo: [ NaN, NaN ] }
// after:  { _: [], foo: [ 'dog', 'cat' ] }

parser('--foo dog cat', { array: { key: 'foo', number: undefined } })
// before: { _: [], foo: [ NaN, NaN ] }
// after:  { _: [], foo: [ 'dog', 'cat' ] }

Root cause

When registering array options, the sub-type (boolean / string / number) was selected by key existence rather than by value:

const assignment = Object.keys(opt).map(function (key) {
  const arrayFlagKeys = { boolean: 'bools', string: 'strings', number: 'numbers' }
  return arrayFlagKeys[key]          // <- fires whenever the key is present
}).filter(Boolean).pop()

So { number: false } (or undefined) still mapped to 'numbers' and turned on number coercion.

Fix

Only enable the sub-type coercion when its value is truthy:

return typeof opt === 'object' && (opt as Record<string, unknown>)[key]
  ? arrayFlagKeys[key]
  : undefined

{ number: true } / { string: true } / { boolean: true } are unchanged; only explicit falsy values now behave as "not set".

Tests

Added a regression test (should not coerce array values as numbers when 'number' is false (#415)) using non-numeric values, since numeric-looking strings are coerced by the global parse-numbers default regardless of this flag.

Verified locally: full suite 363 passing (1 new), gts lint clean.

An array option configured with a falsy sub-type such as
`{ key: 'foo', number: false }` still enabled that coercion, because the
sub-type (`boolean`/`string`/`number`) was chosen by key existence
rather than by value. As a result `{ number: false }` (and
`{ number: undefined }`) coerced array values to numbers, turning
non-numeric values into NaN.

Only enable the sub-type coercion when its value is truthy.

Fixes yargs#415
@shadowspawn

Copy link
Copy Markdown
Member

To be clear: is this Pull Request entirely AI/LLM generated?

There is already a Pull Request open (#536). Is this better than the existing PR?

@simonkundrik

Copy link
Copy Markdown
Author

Thanks for flagging this, and sorry for the noise. I missed #533 when I opened this, it predates mine and fixes the same thing, so that one should take priority. I've closed this in its favor.

And to answer your question directly: yes, this was written with AI assistance. I did review and test the change myself, but I clearly should have checked the open PRs more carefully before opening. Appreciate the heads-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Existence of ‘number’ Key in Options.arrays Changes Parsing

2 participants