commander-js / extra-typings Goto Github PK
View Code? Open in Web Editor NEWInfer strong typings for commander options and action handlers
License: MIT License
Infer strong typings for commander options and action handlers
License: MIT License
I didn't work out a way to make this a types-only package that could be installed into devDependencies
, so probably worth clarifying in README that needs to be installed as a normal (production) dependency. It needs a small shim to map through onto the Commander implementation.
I like to move my action handlers into a separate file and it would be nice if I could somehow infer the arguments and options types that are generated by just passing in an exported instance of the new Command() object. I see that I can pass in my own generic to the constructor but that kind of defeats the purpose of this library. Is there currently a way to do this?
Hi,
I found a type-warning when calling action-handler asynchronously.
In the commander.js code, the return value of the action handler is defined as void | Promise<void>
.
commander.js
https://github.com/tj/commander.js/blob/release/10.x/typings/index.d.ts#L498
extra-typings
https://github.com/commander-js/extra-typings/blob/v10.0.2/index.d.ts#L667
//import { program } from 'commander';
import { program } from '@commander-js/extra-typings';
const actionHandler = async () => {
// any code
};
program.command('sample').action(actionHandler); // ! type-warning
await program.parseAsync();
Thanks!
Based on the README, I would expect the options
variable in the following code to be typed with red
and blue
fields, but it's actually typed as {}
, both in WebStorm and when I compile and try to access the red
field:
import { Command } from "@commander-js/extra-typings";
const program = new Command()
.version("1.0.0")
.option("-r --red", "Only change the pattern on the red goal")
.option("-b --blue", "Only change the pattern on the blue goal")
.command("rainbow")
.action(async () => {
});
const options = program.opts();
typescript
: 5.0.2
commander
: 10.0.1
extra-typings
: 10.0.3
Hello, and thanks for the library.
One problem with this library is that all of the options seem to be strings. Can you show an example in the README of how to use an option that is a number?
e.g.
const command = new Command()
.command("init")
.addOption(
new Option(
"-s, --slot <slot>",
"The slot that you want to use.",
).choices(["1", "2", "3"]),
)
const opts = command.opts();
console.log(typeof opt.slot); // "string" instead of "number"
I have got the package skeleton working, and quite a lot of arguments and option typing working. Ok to publish a version?
% npm publish --dry-run main
npm notice
npm notice ๐ฆ @commander-js/[email protected]
npm notice === Tarball Contents ===
npm notice 1.1kB LICENSE
npm notice 790B README.md
npm notice 36.5kB index.d.ts
npm notice 844B index.js
npm notice 946B package.json
npm notice === Tarball Details ===
npm notice name: @commander-js/extra-typings
npm notice version: 0.1.0
npm notice filename: @commander-js/extra-typings-0.1.0.tgz
npm notice package size: 10.2 kB
npm notice unpacked size: 40.1 kB
npm notice shasum: 95a2f1937534d1c2beaf52fa827e45b0bbf77e13
npm notice integrity: sha512-MIYsGkrUAOSIw[...]wdYeQi1518pMQ==
npm notice total files: 5
npm notice
npm notice Publishing to https://registry.npmjs.org/ (dry-run)
+ @commander-js/[email protected]
For background see: tj/commander.js#1880
Basically, we need a separate type definition file for each of cjs and esm.
Because this repo is all about the TypeScript, I suggest we add the esm.d.mts
file beside the entry point and actually delete the "types"
entry. Some TypeScript gurus recommend this and suggest the "types"
entry is only needed for more complex scenarios when need to point to different folders.
https://arethetypeswrong.github.io/?p=%40commander-js%2Fextra-typings%4010.0.3
My program has wrapper objects for different Command
s and I'm trying to type them appropriately. However, I can't write the necessary types because InferOptions
and associated types aren't exported. I.e.
class Wrapper<Args, Opts> {
constructor(private readonly cmd: Command<Args, Opts>) {}
public specialOption(): Wrapper<Args, ???> { // Can't use InferOptions<Opts, ...> here
return new Wrapper(this.cmd.option("--special"));
}
}
The Argument chaining modifies a single ArgType
each call, which feels far simpler than what Option does with lots of generic types. But it turns out Argument isn't coping with all cases. Found this #29 (comment)
const args = new Command()
.addArgument(new Argument('foo').default('missing').argOptional())
.parse()
.processedArgs;
expectType<string>(args[0]); // FAILS because argOptional added back undefined
If the TypeScript of the client project is configured to generate esm, need the esm.mjs
shim.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.