deno-cliffy
deno-cliffy copied to clipboard
flags without argument ('empty flags') are hard to use as boolean flag
Summary
-
option("--empty-flag", "boolean switch")
may cause surprising behavior withdefault
value. - while there's negatable flag, it may be preferable to not provide one for conciseness.
case 1: empty flag cannot be used as boolean
const boolToStr = (b: boolean) => b ? "true" : "false"
const test1 = await new Command()
.option("--bool-value", "boolean switch")
.action(({ boolValue }) => console.log(boolToStr(boolValue))) // type error
.parse(["--bool-value"])
// boolValue: true | undefined
case 2: default option causes footgun behavior (always evaluates to false
)
const { options } = await new Command()
.option("--bool-value", "boolean switch", { default: false })
.parse(["--bool-value"])
// boolValue: boolean
however, boolValue
always evaluates to false
regardless of whether flag is provided.
const { options } = await new Command()
.option("--bool-value", "boolean switch", { value: (x) => !!x, default: false })
.parse(Deno.args)
console.log({ options })
similarly, default property completely overrides value mapper.
case 3: default value can be only used for action params
const test3 = await new Command()
.option("--bool-value", "boolean switch")
.action(({ boolValue = false }) => console.log(boolValue))
// boolValue: boolean
Possible Solutions?
- document the behavior
- making
default: false
overridable for empty flags
case 1: empty flag cannot be used as boolean
Yeah, i noticed this as well. Maybe we should set the default value by default to false
for boolean flags with no or with optional value.
case 2: default option causes footgun behavior (always evaluates to false)
This was a bug and is already fixed. Will be available in the next release.
that's good to know. would i make a PR for case 1?
I think if we adjust the boolean type to always be a boolean, we should also adjust collectible options to always be an array. Feel free to open a PR, but the typings for the command module are a bit complex. Let me know if you need help!