Skip to content

Typed arguments

Typed arguments are values read by position instead of by name: listy create-list groceries "My groceries". They take the same fields as options, minus aliases, and they are filled from left to right in the order that you declare them.

Define them inside a CLI or subcommand definition, or separately with defineArguments when you want to share them.

import { coerce, defineSubcommand } from "@staticbolt/args-parser";
import * as z from "zod";
const createListCommand = defineSubcommand({
name: "create-list",
arguments: {
listName: {
schema: z.string(),
meta: {
description: "The name of the new list.",
},
},
description: {
schema: z.string().optional(),
meta: {
// Overrides the name shown in help and docs.
name: "list-description",
},
},
},
});
Terminal window
listy create-list groceries "Weekly shopping"

Argument names are shown in kebab-case in help output. meta.name overrides that per argument, and kebabCaseArgumentName: false turns the conversion off for a whole help message.

Rules

  1. Order matters. The first input fills the first argument, and so on.
  2. With allowPositionals: true, no argument may be optional.
  3. With allowPositionals: false, only the last argument may be optional.
  4. Argument names cannot be numeric, since that would make the order ambiguous.

Breaking rule 2 or 3 fails with DefinitionErrorCode.InvalidOptionalArgumentDefinition, and rule 4 with DefinitionErrorCode.InvalidDefinitionArgumentName. Both are reported the first time you run the CLI.

Fields

Same as options, except there is no aliases, and meta has name instead of placeholder:

defineArguments({
argumentName: {
schema: z.string(),
coerce: coerce.string,
exclusive: false,
requires: [],
conflictWith: [],
meta: {
name: "argument-name",
description: "What this argument is for.",
example: "listy create-list groceries",
hidden: false,
},
},
});

Full list in the Argument reference.

See Positionals for how typed arguments and untyped positionals share the same input.