I wrote about a problem that's been bugging me with #Commander.js and #Yargs: .conflicts() and .implies() enforce constraints at runtime, but the type you get back is still a flat object with every field optional. The compiler has no idea which options belong together.
The post walks through what happens when you express the same constraints in the parser structure instead, and how #TypeScript turns that into a discriminated union where each branch carries only its own fields.
Second half covers a less obvious question: what happens when values come from env vars, config files, or prompts instead of argv, and whether the constraints should still hold across all of them.
https://hackers.pub/@hongminhee/2026/optique-10-discriminated-unions-for-cli
#JavaScript #CLI #Optique