yargs: alias does not seem to work

Aliases appear to be completely ignored with 17.4.0. Take this test script we’ll call yargs.ts:

import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { basename } from 'path';

async function main(args: string[]) {
	const parser = yargs(args)
		.scriptName(`${basename(process.argv[0])} ${basename(process.argv[1])}`)
		.usage('$0 -e <env> [prop1 prop2 ...]')
		.options({
			env: {
				alias: ['e'],
				type: 'string',
				demandOption: true,
				choices: ['dev', 'stage', 'prod'] as const,
				nargs: 1,
			},
		})
		.help('h')
		.alias('h', 'help')
		.wrap(100)
		.version(false);
	// If we actually get this far, print out some debug info.
	// But the script doesn't actually get this far before printing help and exiting.
	console.log(JSON.stringify(parser, null, 2));
	const argv = await parser.parse();
	console.log(JSON.stringify(argv, null, 2));
}

if (require.main === module) {
	main(hideBin(process.argv));
}

if I run it via ts-node test.ts -e dev, the output looks like:

ts-node test.ts -e <env> [prop1 prop2 ...]

Options:
  -e, --env                                    [string] [required] [choices: "dev", "stage", "prod"]
  -h, --help  Show help                                                                    [boolean]
      ---e
      --dev

Missing required argument: env

Not only is it reporting env as missing, but it seems to be adding ---e and --dev to the list of options in the help text.

I’ve tried this with node 12 (what I’m officially stuck on for a few more weeks) and node 14 (just to be sure), and with yargs 16.x and 17.x with the same results.

Running ts-node test.ts --env dev works as expected and results in:

{
  "customScriptName": true,
  "parsed": false,
  "$0": "ts-node test.ts",
  "argv": {
    "_": [],
    "env": "dev",
    "--env": "dev",
    "$0": "ts-node test.ts"
  }
}
{
  "_": [],
  "env": "dev",
  "--env": "dev",
  "$0": "ts-node test.ts"
}

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 18 (13 by maintainers)

Most upvoted comments

jly36963 was right with suspicion that TypeScript compilation is the problem.

I recently discovered that the command-line flags appearing in the help is a big red flag that the TypeScript import is not working as intended. The short version is turn on esModuleInterop. For more detail of current research, see: https://github.com/yargs/yargs/issues/2010#issuecomment-1441301656

Passing a string or an array of strings to yargs() should have similar behavior

Like I said, it doesn’t do that for me. I’m currently using node 12 (stupid enterprise dependency) but had similar behavior with 14 (where we’ll be in a few weeks). Happy to help debug more and figure out what’s different about my environment.

I’ve tried your example code as such:

import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

yargs(hideBin(process.argv))
	.command(
		'$0',
		'default desc',
		(yargs) => yargs,
		(argv) => console.log(argv),
	)
	.command(
		'cmd1',
		'cmd1 desc',
		(yargs) =>
			yargs
				// chained onto command builder
				.option('bar', { type: 'string', alias: 'b', required: true }),
		(argv) => console.log(argv),
	)
	// chained globally
	.option('foo', { type: 'string', alias: 'f', required: true })
	.strict()
	.parse();

When I invoke with ts-node test.ts -f abc the output is:

test.ts

default desc

Commands:
  test.ts       default desc                                           [default]
  test.ts cmd1  cmd1 desc

Options:
      --help     Show help                                             [boolean]
      --version  Show version number                                   [boolean]
  -f, --foo                                                  [string] [required]
      ---f
      --abc

Missing required argument: foo

The same happens if I compile with tsc and then run node test.js -f abc

Command-based required options also fail (e.g. via node test.js cmd1 -f abc -b 123):

test.js cmd1

cmd1 desc

Options:
      --123
      --help     Show help                                             [boolean]
      --version  Show version number                                   [boolean]
  -f, --foo                                                  [string] [required]
  -b, --bar                                                  [string] [required]
      --cmd1
      ---f
      --abc
      ---b

Missing required arguments: foo, bar