Skip to content

Commit 24d145a

Browse files
committed
feat: add helper types for inferring parser values
1 parent db8ed3a commit 24d145a

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export { opt, pos } from './opt.js';
3838
export type {
3939
CallableOptionsParser,
4040
CallablePositionalsParser,
41+
InferParserPositionals,
42+
InferParserValues,
4143
} from './opt.js';
4244

4345
// OSC utilities for terminal hyperlinks

src/opt.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,31 @@ export type CallableOptionsParser<V> = (<V2, P2 extends readonly unknown[]>(
7070
) => Parser<V & V2, P2>) &
7171
Parser<V, readonly []>;
7272

73+
/**
74+
* Extract the inferred values type from a CallableOptionsParser or Parser.
75+
*
76+
* Useful for getting the type of global options to use elsewhere in your code.
77+
*
78+
* @example
79+
*
80+
* ```typescript
81+
* const globalOptions = opt.options({
82+
* verbose: opt.boolean(),
83+
* 'output-dir': opt.string(),
84+
* });
85+
*
86+
* // Extract the type for use elsewhere
87+
* type GlobalOpts = InferParserValues<typeof globalOptions>;
88+
* // { verbose: boolean | undefined; 'output-dir': string | undefined }
89+
* ```
90+
*/
91+
export type InferParserValues<T> =
92+
T extends CallableOptionsParser<infer V>
93+
? V
94+
: T extends Parser<infer V, readonly unknown[]>
95+
? V
96+
: never;
97+
7398
/**
7499
* Create a Parser from an options schema that can also merge with existing
75100
* parsers.
@@ -362,6 +387,30 @@ export type CallablePositionalsParser<P extends readonly unknown[]> = (<
362387
) => Parser<V2, readonly [...P2, ...P]>) &
363388
Parser<object, P>;
364389

390+
/**
391+
* Extract the inferred positionals tuple type from a CallablePositionalsParser
392+
* or Parser.
393+
*
394+
* @example
395+
*
396+
* ```typescript
397+
* const positionals = pos.positionals(
398+
* pos.string({ name: 'source', required: true }),
399+
* pos.string({ name: 'dest', required: true }),
400+
* );
401+
*
402+
* // Extract the type for use elsewhere
403+
* type Positionals = InferParserPositionals<typeof positionals>;
404+
* // readonly [string, string]
405+
* ```
406+
*/
407+
export type InferParserPositionals<T> =
408+
T extends CallablePositionalsParser<infer P>
409+
? P
410+
: T extends Parser<unknown, infer P>
411+
? P
412+
: never;
413+
365414
/**
366415
* Create a Parser from positional definitions that can also merge with existing
367416
* parsers.

0 commit comments

Comments
 (0)