Merge pull request #31603 from steffenvv/yargs-unknown

yargs: Fall back to unknown instead of any for unknown options
This commit is contained in:
Wesley Wigham
2018-12-24 21:02:14 -08:00
committed by GitHub
3 changed files with 60 additions and 30 deletions
+9 -4
View File
@@ -2,12 +2,17 @@
// Project: https://github.com/yargs/yargs-parser#readme
// Definitions by: Miles Johnson <https://github.com/milesj>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
import { Arguments as YargsArguments } from 'yargs';
// TypeScript Version: 2.2
declare namespace yargsParser {
type Arguments = YargsArguments<{}>;
interface Arguments {
/** Non-option arguments */
_: string[];
/** The script name or node command */
$0: string;
/** All remaining options */
[argName: string]: any;
}
interface DetailedArguments {
argv: Arguments;
+6 -6
View File
@@ -8,7 +8,7 @@
// Teddy Cross <https://github.com/tkazec>
// Steffen Viken Valvåg <https://github.com/steffenvv>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
// TypeScript Version: 3.0
// The following TSLint rules have been disabled:
// unified-signatures: Because there is useful information in the argument names of the overloaded signatures
@@ -27,7 +27,7 @@
declare namespace yargs {
// The type parameter T is the expected shape of the parsed options.
// Arguments<T> is those options plus _ and $0, and an indexer falling
// back to any for unknown options.
// back to unknown for unknown options.
//
// For the return type / argv property, we create a mapped type over
// Arguments<T> to simplify the inferred type signature in client code.
@@ -96,14 +96,14 @@ declare namespace yargs {
* Use '.demandCommand()' or '.demandOption()' instead
*/
demand<K extends keyof T>(key: K | ReadonlyArray<K>, msg?: string | true): Argv<Defined<T, K>>;
demand(key: string | ReadonlyArray<string>, msg: string): Argv<T>;
demand<K extends string>(key: K | ReadonlyArray<K>, msg?: string | true): Argv<T & { [key in K]: unknown }>;
demand(key: string | ReadonlyArray<string>, required?: boolean): Argv<T>;
demand(positionals: number, msg: string): Argv<T>;
demand(positionals: number, required?: boolean): Argv<T>;
demand(positionals: number, max: number, msg?: string): Argv<T>;
demandOption<K extends keyof T>(key: K | ReadonlyArray<K>, msg?: string | true): Argv<Defined<T, K>>;
demandOption(key: string | ReadonlyArray<string>, msg?: string): Argv<T>;
demandOption<K extends string>(key: K | ReadonlyArray<K>, msg?: string | true): Argv<T & { [key in K]: unknown }>;
demandOption(key: string | ReadonlyArray<string>, demand?: boolean): Argv<T>;
demandCommand(): Argv<T>;
@@ -258,7 +258,7 @@ declare namespace yargs {
/** The script name or node command */
$0: string;
/** All remaining options */
[argName: string]: any;
[argName: string]: unknown;
};
interface RequireDirectoryOptions {
@@ -372,7 +372,7 @@ declare namespace yargs {
O extends { normalize: true } ? string :
O extends { choices: ReadonlyArray<infer C> } ? C :
O extends { coerce: (arg: any) => infer T } ? T :
any;
unknown;
type InferredOptionTypes<O extends { [key: string]: Options }> = { [key in keyof O]: InferredOptionType<O[key]> };
+45 -20
View File
@@ -14,7 +14,7 @@ const stringVal = 'string';
function xup() {
const argv = yargs.argv;
if (argv.rif - 5 * argv.xup > 7.138) {
if (typeof argv.rif === "number" && typeof argv.xup === "number" && argv.rif - 5 * argv.xup > 7.138) {
console.log('Plunder more riffiwobbles!');
} else {
console.log('Drop the xupptumblers!');
@@ -47,6 +47,7 @@ function divide() {
const argv = yargs
.usage('Usage: $0 -x [num] -y [num]')
.demand(['x', 'y'])
.number(['x', 'y'])
.argv;
console.log(argv.x / argv.y);
@@ -121,7 +122,7 @@ function Argv$argv() {
function Argv_parsing() {
const argv1 = yargs.parse();
const argv2 = yargs(['-x', '1', '-y', '2']).argv;
const argv2 = yargs(['-x', '1', '-y', '2']);
const argv3 = yargs.parse(['-x', '1', '-y', '2']);
console.log(argv1.x, argv2.x, argv3.x);
}
@@ -671,7 +672,7 @@ type Color = "red" | "blue" | "green";
const colors: ReadonlyArray<Color> = ["red", "blue", "green"];
function Argv$inferOptionTypes() {
// $ExpectType { [x: string]: any; a: (string | number)[] | undefined; b: boolean | undefined; c: number; n: number | undefined; s: string | undefined; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; c: number; n: number | undefined; s: string | undefined; _: string[]; $0: string; }
yargs
.option("a", { type: "array" })
.option("b", { type: "boolean" })
@@ -680,14 +681,14 @@ function Argv$inferOptionTypes() {
.option("s", { type: "string" })
.argv;
// $ExpectType { [x: string]: any; a: number; b: boolean; c: string; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: number; b: boolean; c: string; _: string[]; $0: string; }
yargs
.option("a", { default: 42 })
.option("b", { default: false })
.option("c", { default: "tmp" })
.argv;
// $ExpectType { [x: string]: any; a: (string | number)[] | undefined; b: boolean | undefined; n: number | undefined; s: string | undefined; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: (string | number)[] | undefined; b: boolean | undefined; n: number | undefined; s: string | undefined; _: string[]; $0: string; }
yargs
.option("a", { array: true })
.option("b", { boolean: true })
@@ -695,7 +696,7 @@ function Argv$inferOptionTypes() {
.option("s", { string: true })
.argv;
// $ExpectType { [x: string]: any; choices: Color; coerce: Date | undefined; count: number; normalize: string | undefined; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; choices: Color; coerce: Date | undefined; count: number; normalize: string | undefined; _: string[]; $0: string; }
yargs
.option("choices", { choices: colors, required: true })
.option("coerce", { coerce: () => new Date() })
@@ -735,21 +736,33 @@ function Argv$inferRequiredOptionTypes() {
// $ExpectType string
yargs.string("x").demand("x").argv.x;
// $ExpectType string
yargs.demand("x").string("x").argv.x;
// $ExpectType string
yargs.string("x").demandOption("x").argv.x;
// $ExpectType string | undefined
yargs.string("x").demandOption("x", false).argv.x;
// $ExpectType { [x: string]: any; x: string; y: number; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; x: string; y: number; _: string[]; $0: string; }
yargs.string("x").number("y").demandOption(["x", "y"]).argv;
// $ExpectType { [x: string]: any; x: string; y: number; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; x: string; y: number; _: string[]; $0: string; }
yargs.string("x").number("y").demandOption(["x", "y"], true).argv;
// $ExpectType { [x: string]: any; x: string | undefined; y: number | undefined; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: string[]; $0: string; }
yargs.string("x").number("y").demandOption(["x", "y"], false).argv;
// $ExpectType { [x: string]: unknown; x: string; y: number; _: string[]; $0: string; }
yargs.demandOption(["x", "y"]).string("x").number("y").argv;
// $ExpectType { [x: string]: unknown; x: string; y: number; _: string[]; $0: string; }
yargs.demandOption(["x", "y"], true).string("x").number("y").argv;
// $ExpectType { [x: string]: unknown; x: string | undefined; y: number | undefined; _: string[]; $0: string; }
yargs.demandOption(["x", "y"], false).string("x").number("y").argv;
// $ExpectType string
yargs.option("x", { string: true, require: true }).argv.x;
@@ -776,32 +789,32 @@ function Argv$inferRequiredOptionTypes() {
}
function Argv$inferMultipleOptionTypes() {
// $ExpectType { [x: string]: any; a: string; b: boolean; c: number; d: number; e: number; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: string; b: boolean; c: number; d: number; e: number; _: string[]; $0: string; }
yargs
.option({ a: { default: "a" }, b: { default: false } })
.number(["c", "d", "e"])
.demandOption(["c", "d", "e"])
.argv;
// $ExpectType { [x: string]: any; a: string; b: boolean; c: number; d: number; e: number; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: string; b: boolean; c: number; d: number; e: number; _: string[]; $0: string; }
yargs
.options({ a: { default: "a" }, b: { default: false } })
.number(["c", "d", "e"])
.demandOption(["c", "d", "e"])
.argv;
// $ExpectType { [x: string]: any; a: number; b: string; c: boolean; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: number; b: string; c: boolean; _: string[]; $0: string; }
yargs
.default({ a: 42, b: "b", c: false })
.argv;
// $ExpectType { [x: string]: any; a: number; b: string; c: Date; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: number; b: string; c: Date; _: string[]; $0: string; }
yargs
.coerce({ a: Date.parse, b: String.prototype.toLowerCase, c: (s: string) => new Date(s) })
.demandOption(["a", "b", "c"])
.argv;
// $ExpectType { [x: string]: any; a: number | undefined; b: string | undefined; c: Color; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; a: number | undefined; b: string | undefined; c: Color; _: string[]; $0: string; }
yargs
.choices({ a: [1, 2, 3], b: ["black", "white"], c: colors })
.demandOption("c")
@@ -809,20 +822,20 @@ function Argv$inferMultipleOptionTypes() {
}
function Argv$inferOptionTypesForAliases() {
// $ExpectType { [x: string]: any; u: string | undefined; url: string | undefined; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; u: string | undefined; url: string | undefined; _: string[]; $0: string; }
yargs
.option("u", { type: "string" })
.alias("u", "url")
.argv;
// $ExpectType { [x: string]: any; v: boolean; loud: boolean; noisy: boolean; verbose: boolean; n: boolean; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; v: boolean; loud: boolean; noisy: boolean; verbose: boolean; n: boolean; _: string[]; $0: string; }
yargs
.option("v", { default: false })
.alias("v", ["loud", "noisy", "verbose"])
.alias("n", "noisy")
.argv;
// $ExpectType { [x: string]: any; n: number; count: number; num: number; _: string[]; $0: string; }
// $ExpectType { [x: string]: unknown; n: number; count: number; num: number; _: string[]; $0: string; }
yargs
.option("n", { number: true, demandOption: true })
.alias("n", "count")
@@ -921,13 +934,25 @@ function Argv$inferRepeatedOptionTypes() {
yargs.boolean("a").option("a", { string: true }).option("a", { number: true }).argv.a;
}
function Argv$fallbackToAnyForUnknownOptions() {
// $ExpectType any
function Argv$fallbackToUnknownForUnknownOptions() {
// $ExpectType unknown
yargs.argv.bogus;
// $ExpectType any
// $ExpectType unknown
yargs
.option({a: { type: "string" }, b: { type: "boolean" } })
.argv
.bogus;
const argv = yargs.option({ a: {}, b: {} }).option("c", {}).argv;
// $ExpectType unknown
argv.a;
// $ExpectType unknown
argv.b;
// $ExpectType unknown
argv.c;
// $ExpectError
const x: string = yargs.argv.x;
return x;
}