| name | type-flag |
| description | Strongly-typed Node.js argv parser. Schema syntax (String/Number/Boolean, arrays, custom types, aliases, defaults, single-char names), return shape (flags/unknownFlags/positional args), flag forms (long/short/grouping, = : . delimiters, kebab↔camelCase), boolean negation via `--no-`, and the `ignore` callback for multi-command dispatch. Use when working with type-flag or building CLIs on top of it (e.g. cleye). |
type-flag
Quick start
import { typeFlag } from 'type-flag'
const parsed = typeFlag({
name: String,
age: { type: Number, alias: 'a' },
})
parsed.flags.name
parsed.flags.age
parsed.unknownFlags
parsed._
Schema
| Form | Example | Meaning |
|---|
| Shorthand | flag: String | Type only |
| Object | flag: { type: String, alias: 'f', default: 'x' } | Type + options |
| Array | flag: [String] or { type: [String] } | Collect multiple values |
| Custom type | flag: (raw: string) => MyType | Any (string) => T |
| Single-char name | x: Number | Matches -x, NOT --x |
Type options:
| Option | Type | Notes |
|---|
type | TypeFunction | [TypeFunction] | Parser; wrap in [] for arrays |
alias | string (1 char) | Forbidden when flag name is 1 char |
default | T | (() => T) | Use a function for mutable defaults (objects/arrays) |
Return shape
{
flags: { [name]: InferredType },
unknownFlags: { [name]: (string | boolean)[] },
_: string[] & { '--': string[] },
}
Flag forms
| Input | Behavior |
|---|
--flag value / --flag=value | Long form |
-f value / -f=value | Short form (alias or single-char name) |
-abc | Group: each char matches an alias or single-char name independently |
--some-flag | kebab-case → camelCase (someFlag) unless schema key is kebab |
--flag:value / --flag.value | : and . also delimit values (useful for --define:K=V, --env.KEY=V) |
-xvalue (concatenated) | ⚠️ Parsed as GROUP, not x=value. Use -x value or -x=value. |
Single-char flag names vs aliases
Both produce short flags that group identically (-ab, -av, mixed — all work). The difference is OUTPUT placement:
| Pattern | When | Example |
|---|
Single-char name ({ x: Number }) | Short form IS the flag (coordinates, -h/--help as distinct entries) | Key lands in flags.x |
Alias ({ verbose: { alias: 'v' } }) | --verbose and -v should set the same value | Both forms feed flags.verbose |
Single-char names match -x but NOT --x — this preserves schemas like { h: Boolean, help: Boolean } where -h and --help must stay distinct (rg-style short-vs-long help).
Boolean negation (opt-in)
typeFlag({ verbose: Boolean }, argv, { booleanNegation: true })
Only affects Boolean-typed, schema-known flags. --no-X for non-boolean or unknown falls through to unknownFlags.
Explicit =false always works regardless of booleanNegation:
ignore callback
Skip parsing specific tokens (leave them in argv). Called for each token:
ignore?: (
type: 'known-flag' | 'unknown-flag' | 'argument',
flagOrArgv: string,
value: string | undefined,
) => boolean | void
Two common patterns:
typeFlag({}, argv, { ignore: type => type === 'unknown-flag' })
let stop = false
typeFlag(schema, argv, {
ignore: (type) => {
if (stop) return true
if (type === 'argument') { stop = true; return true }
},
})
argv is mutated: type-flag removes parsed tokens. Pass process.argv.slice(2) (or a copy) to see what's left.
getFlag — one-off extraction
import { getFlag } from 'type-flag'
const name = getFlag('--name', String)
const age = getFlag('-a,--age', Number)
const tags = getFlag('-t,--tag', [String])
Same argv-mutation behavior as typeFlag.
Gotchas
| Gotcha | Detail |
|---|
| Negative numbers look like flag groups | --num -123 is parsed as -1 -2 -3 (char group). Use --num=-123 or --num=-Inf. |
argv is mutated | Parsed tokens are spliced out. Don't share argv with other parsers after. |
| Frozen argv throws | Object.freeze(argv) breaks the splice. Pass a mutable copy. |
unknownFlags keys are raw | NOT camelCased — so you can distinguish --some-flag from --someFlag. |
| Reserved chars in names | \s, ., :, = forbidden in flag names (they're delimiters). |
| kebab schema key | If schema key is 'some-flag', only --some-flag / --someFlag both map to it, but output key stays kebab. |
| Default functions throw | A throwing default: () => ... propagates. |
| Custom-type errors wrap | Parser errors include the flag name in the thrown message. |
Related
For full CLI framework with help generation and subcommands, see cleye (built on type-flag).