15

Here is what I tried (code adapted the code from the example in the yargs github readme):

// main.ts

import {Argv} from "yargs";


console.info(`CLI starter.`);

function serve(port: string) {
    console.info(`Serve on port ${port}.`);
}

require('yargs')
    .command('serve', "Start the server.", (yargs: Argv) => {
        yargs.option('port', {
            describe: "Port to bind on",
            default: "5000",
        }).option('verbose', {
            alias: 'v',
            default: false,
        })
    }, (args: any) => {
        if (args.verbose) {
            console.info("Starting the server...");
        }
        serve(args.port);
    }).argv;

Results:

npm run-script build; node build/main.js --port=432 --verbose

> typescript-cli-starter@0.0.1 build /Users/kaiyin/WebstormProjects/typescript-cli-starter
> tsc -p .

CLI starter.

Looks like yargs has no effects here.

Any idea how to get this to work?

andrewdotn
  • 32,721
  • 10
  • 101
  • 130
qed
  • 22,298
  • 21
  • 125
  • 196

3 Answers3

14

I adapted the code from the example in the yargs github readme, turns out it's not meant to be a complete example. ¯_(ツ)_/¯

Anyways, I figured out how to do it:

#!/usr/bin/env node

import yargs, {Argv} from "yargs";

let argv = yargs
    .command('serve', "Start the server.", (yargs: Argv) => {
        return yargs.option('port', {
            describe: "Port to bind on",
            default: "5000",
        }).option('verbose', {
            alias: 'v',
            default: false,
        })
    }).argv;

if (argv.verbose) {
    console.info("Verbose mode on.");
}

serve(argv.port);

function serve(port: string) {
    console.info(`Serve on port ${port}.`);
}

You can find the complete typescript-cli-starter repo here: https://github.com/kindlychung/typescript-cli-starter

Peter Lamberg
  • 8,151
  • 3
  • 55
  • 69
qed
  • 22,298
  • 21
  • 125
  • 196
  • You are still importing 'yargs' twice. Consider doing `let argv = yargs.command(...) ...` – E_net4 Jul 13 '17 at 10:23
  • Yep, now fixed. – qed Jul 13 '17 at 10:24
  • 3
    I tested with new versions of stuff and edited the answer accordingly. With the `* as yargs` form of import I was getting the error `cannot redefine property: default`. (Adding the error here in case somebody else is googling for that error and yargs). The correct way is to import the default export of yargs with `import yargs from "yargs"`. – Peter Lamberg Jul 23 '20 at 20:03
  • Had to remove the `return` statement under the `.command` function to satisfy the typechecker, otherwise got a "No overload matches this call" type error. After that worked great! – Roman Scher Jul 26 '22 at 18:52
  • After updating something, not sure what, the typechecker got angry if I didn't use the `ArgumentsCamelCase` type in my `.command` callback function definition when destructuring the arguments, so had to specify it like `({ port }: ArgumentsCamelCase<{ port: string }>) => {}` – Roman Scher Jul 27 '22 at 15:23
7

a minimalistic example

import * as yargs from 'yargs'

    let args = yargs
        .option('input', {
            alias: 'i',
            demandOption: true
        })
        .option('year', {
            alias: 'y',
            description: "Year number",
            demandOption: true
        }).argv;

    console.log(JSON.stringify(args));
Wouter van Nifterick
  • 23,603
  • 7
  • 78
  • 122
Andrey
  • 1,752
  • 18
  • 17
2

An example including a command and callback function:

import yargs, { Argv, ArgumentsCamelCase } from 'yargs'
import { hideBin } from 'yargs/helpers'

yargs(hideBin(process.argv))
    .command(
        'select <color>',
        'Select a color to display',
        (args: Argv) => {
            args.positional('color', {
                describe: 'The color to display. e.g.) Blue to display blue'
            })
        },
        ({ color }: ArgumentsCamelCase<{ color: string }>) => {
            console.log(`Your color is ${color}!`)
        }
    )
    .demandCommand()
    .parse()

Dmitriy Botov
  • 2,623
  • 1
  • 15
  • 12
Roman Scher
  • 1,162
  • 2
  • 14
  • 18