-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
narrow value types based on choices #29
Conversation
Cool! Adding support for
|
What does the [Edit] Oh, deconstructing the array so get the union of the values. Got it. 💡 |
The main Argument tests are in a section titled If you add a test like this, where I think I got the expected type right:
TypeScript does not complain because the type checking is a bit weaker with default settings. But if you run the tests using I have not worked out how to fix it yet, just spotted that your change is overwriting |
Take a look at |
Yeah variadic is going to be interesting. I just tried it out with this solution and it does not currently work. It might be necessary to introduce something like a |
Yes. Looking at Option:
Keeping the types explicit and dumb at this level and doing the hard work in the later Infer routines with all the information available has worked out reasonably well. At some level in the Infer layers, I think |
Updated with support for variadic args and options. It's a bit... dense but I basically did what I said above about introducing a ChoiceT generic. I made a small update to I tried to do what you suggested above with reusing DefaultT or CoerceT but that quickly turned into whack-a-mole with other edge cases so I added the ChoiceT type. Also added several more tests |
I think However, I am not sure that is still possible with Here are some tests to demonstrate that ordering does not matter for Option, but does for Argument because calling import { Argument, Option, Command } from '..'; import { expectType } from 'tsd'; |
I suspect Argument could track two types instead of just one: the base Not sure if that will be easier to reason about than saving up the types for a big Infer when |
Ah ha! I just found an existing bug showing that Argument repeatedly modifying The two-type approach I was wondering about would be able to cope but still require some extra logic. Currently leaning towards the Option approach of tracking multiple types. I do prefer the idea of Option and Argument being similar in handling, much as I wish it was all easier... Failing case: const args = new Command()
.addArgument(new Argument('foo').default('missing').argOptional())
.parse()
.processedArgs;
expectType<string>(args[0]); // FAILS because argOptional added back undefined |
I suggest you wait while I have a go at rewriting the Argument type handling. (Unless you are really keen!) |
I focused on reworking Argument generics without trying to make |
I'll wait for that other PR to go in before picking this one up :) Might be a couple days before I can circle back to this anyway. |
Just pushed up some changes. Looks like I bungled the merge a bit. Will come back to that in a bit but I think all the functional parts are there |
Oh I see, PR was just based off the wrong branch |
Reverted some autoformatting. I think this is ready for another review now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
Co-authored-by: John Gee <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Released in v10.0.3 |
Updates the
.choices()
type signature of bothOption
andArgument
to narrow the type to a specific string when const string arrays are used as the input.The tests should make it pretty clear what's going on, but basically in a situation where choices is a const array, the type will be inferred to be a union of strings rather than just string: