Open MatthiasKunnen opened 4 years ago
@MatthiasKunnen The types come from @types/yargs
(a separate project) and are not a 100% match of what yargs really does. We are working at the moment to port yargs to typescript and publish native types. However, I doubt we will be able to include camel (or kebab) case expansion into the returned types.
That said, let's come back to your need. In your above example, you define the option name as noProgress
, so you should have:
noProgress
in the resulting type from @types/yargs
(at compile time), but not no-progress
(I don't think it is even possible to infer this at compile time with typescript)noProgress
and no-progress
in the actual js parsing result (at run time)Isn't it what you are trying to achieve (using noProgress in your code, an having your users use no-progress in the CLI)?
Converting between camel and kebab case is indeed not supported by TypeScript's type system.
My problem is that given the following code:
const argv = yargs
.options({
noProgress: {
default: false,
desc: 'Disable progress output, useful in terminals that do not support overwriting.',
type: 'boolean',
},
})
.argv;
The CLI help is:
Options:
--help Show help [boolean]
--version Show version number [boolean]
--noProgress Disable progress output, useful in terminals that do not support
overwriting. [boolean] [default: false]
I would like the CLI help to display --no-progress
.
This also applies to the generated completions: they suggest --noProgress
instead of --no-progress
.
@mleguen, could you change the label from question to enhancement or feature request?
@MatthiasKunnen, well, I am not sure yet an enhancement would be needed.
Wouldn't the following code suite your needs?
const argv = yargs
.options({
'no-progress': {
default: false,
desc: 'Disable progress output, useful in terminals that do not support overwriting.',
type: 'boolean',
},
})
.argv;
It returns both no-progress
and noProgress
in the parsing results, and shows --no-progress
in the help message.
That'd likely mess with TypeScript however, as it would infer no-progress
(since it can't transform the key into camelCase)
Yes, you are right.
TS 4.1 should be able to handle this feature now.
@jasonkuhrt I've been nudging people towards continuing to use @types/yargs
, since the delta between this project and yargs was pretty huge ... sounds like we could address this feature request by making a patch to DefinitelyTyped?
It seems this conversation died, however, it remains an outstanding problem, e.g.
const argv = yargs
.env('CAS')
.help()
.options({
'app-path': {
demand: true,
type: 'string',
},
})
.parseSync();
export type Configuration = typeof argv;
Now, lets say that I want to mock Configuration
. I cannot do just:
const configuration: Configuration = {
appPath: '',
};
because app-path
is missing.
Ideally, I would want to pick that types only include camelCase
.
I tried removing all kebab-case properties, but for whatever reason that removes all properties.
const argv = yargs
.env('CAS')
.help()
.options({
'app-path': {
demand: true,
type: 'string',
},
})
.parseSync();
type Configuration = Omit<typeof argv, `${string}-${string}`;
This causes Configuration
to become:
{
[x: string]: unknown,
[x: number]: unknown
}
@bcoe Any update on this?
It keeps bitting us that we reference the config by both camelCase
and kebab-case
.
Trying to find a way to ensure that only one is surfaced.
The type definitions for @types/yargs
do not modify the inferred types for the parserConfiguration
like strip-dashed
, they always include both the plain option and the camelCase variation.
Rolling your own like attempted in https://github.com/yargs/yargs/issues/1679#issuecomment-1142386444 could perhaps do:
type OmitDashed<T> = {[K in keyof T as K extends `${infer a}-${infer b}` ? never : K]: T[K]}
type MyConfiguration = OmitDashed<typeof argv>;
There is extra work required to explicitly add an option starting with no-
like no-progress
in the first example: https://github.com/yargs/yargs/issues/1679#issue-644148637
The default parsing behaviour will turn a command-line option --no-progress
into progress: false
and not store it as no-progess
or noProgress
.
So may need to use boolean-negation
in the parserConfiguration
too.
The DefinitelyTyped work is a separate project so may want to open discussion issues there to discuss what is feasible to improve in the inferred types:
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions?discussions_q=yargs
I have not found a way to do this and would like to do the following. Given the following config,
noProgress
should be in the resulting argv but the CLI help and parser should useno-progress
. This follows both conventions for camelCase in JS/TS and kebab-case in the CLI.Code:
CLI help:
why
I want to use this approach instead of the camel case expansion because the camel case expansion does not give the return type I want (Using TypeScript).
I could maintain an interface with CLI options but that introduces the potential for the argv and interface to diverge when you forget to update either which could cause bugs.