news 2026/10/30 4:18:34

Optique解析器组合子速查表:object、or、merge、optional、multiple、map六大核心函数完全掌握

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Optique解析器组合子速查表:object、or、merge、optional、multiple、map六大核心函数完全掌握

【免费下载链接】optique

Type-safe combinatorial CLI parser for TypeScript

项目地址:https://gitcode.com/gh_mirrors/op/optique
点击查看免费下载

Optique 是一个面向 TypeScript 的类型安全组合式 CLI 解析器(type-safe combinatorial CLI parser)。这份速查表聚焦最常被用到的六大组合子——object()、or()、merge()、optional()、multiple()、map(),用最少的代码讲清楚每个函数"做什么、类型如何变化、什么时候该选它",帮你在构建子命令、共享选项、重复参数等场景时快速选对组合子。

📌 一屏速查表:六大组合子怎么选

组合子一句话定位结果类型所在模块
object()把命名字段组成结构化对象对象(字段名→值)@optique/core/constructs
or()互斥备选,按顺序逐个尝试联合类型(可收窄)@optique/core/constructs
merge()把多个解析器合并成一个对象合并后的对象@optique/core/constructs
optional()允许字段缺失T \| undefined@optique/core/modifiers
multiple()收集重复出现为数组数组T[]@optique/core/modifiers
map()变换解析出的值映射后的类型U@optique/core/modifiers

记忆口诀:object 按名分组、or 选一个、merge 组合并组、optional 允许缺席、multiple 收集重复、map 变换结果。

1️⃣ object():多数 CLI 结构的地基

object()接收一个"字段名 → 解析器"的映射,返回结构化对象,是几乎所有 CLI 应用的基础构件。

const serverConfig = object({ name: argument(string({ metavar: "NAME" })), port: option("-p", "--port", integer()), verbose: option("-v", "--verbose"), });

关键要点:

  • 无需手写类型注解,InferValue<typeof serverConfig>会自动推导出完整对象类型。
  • 第一个参数可传标签(如object("Network", {...})),帮助文本中会显示为分组标题。
  • 整体优先级取组成解析器中的最高值,因此内嵌的 command 字段会优先被尝试。

源码入口:packages/core/src/constructs.ts。

2️⃣ or():互斥模式与子命令分发

or()按顺序尝试每个备选,直到某一个成功,是"server 模式 / client 模式"以及子命令结构的标准做法。

const gitLike = or( command("add", object({ type: constant("add"), files: multiple(argument(string())), })), command("commit", object({ type: constant("commit"), message: option("-m", "--message", string()), })), );

关键要点:

  • 配合constant()字段会形成 TypeScript 判别联合(discriminated union),可对type字段写类型安全的switch。
  • 单次or()调用最多 15 个分支,更多时拆成嵌套分组。
  • 想让"一个都不选"也合法并得到undefined,用optional()包住整个or()。
  • 错误消息可通过errors.noMatch选项自定义,会根据上下文(期望的是 option / command / argument)自动适配措辞。

源码入口:packages/core/src/constructs.ts;可运行示例见 examples/patterns/subcommands.ts 与 examples/patterns/mutually-exclusive-options.ts。

3️⃣ merge():模块化复用选项组

merge()把多个"产生对象"的解析器合并为一个解析器,是实现"同一选项组在多个命令间复用"的关键。

const globalOptions = object({ verbose: option("-v", "--verbose"), config: option("-c", "--config", string()), }); const deployParser = merge(globalOptions, deployOptions);

关键要点:

  • 最常见模式是merge(globals, or(...)):把全局选项提到每个子命令分支之外,避免在每条命令里重复声明。
  • 不限于object():withDefault()、map()等产生对象的解析器同样可以合并,类型会智能推断。
  • 与or()一样受 15 个参数上限约束;也支持标签参数,在帮助文本中整组显示。
  • 可用optional()包裹某个对象组,让整个分组变成"可选功能组",不与必填参数冲突。

源码入口:packages/core/src/constructs.ts;实战配方见 examples/patterns/shared-options.ts。

4️⃣ optional():显式允许"未提供"

optional()让任何解析器变成可选:匹配成功就返回其值,失败则返回undefined,不报错、不消耗输入。

const backupConfig = object({ source: argument(string({ metavar: "SRC" })), compress: optional(option("-c", "--compress", choice(["gzip", "bzip2"]))), });

关键要点:

  • 类型从T变为T | undefined,编译器会强制你处理"值可能不存在"的情况,避免运行时误判。
  • 当"值缺失"本身有语义时使用它;如果你想要一个兜底值而不是undefined,应改用withDefault()。
  • 它是把or()变成"全部可选"的标准搭配:optional(or(flagA, flagB))。

源码入口:packages/core/src/modifiers.ts。

5️⃣ multiple():重复参数收集成数组

multiple()允许解析器多次匹配,并把所有结果收集到数组中,适合多个输入文件、include 路径、环境变量等可重复选项。

const parser = object({ files: multiple(argument(string()), { min: 1, max: 5 }), includes: multiple(option("-I", "--include", string())), });

关键要点:

  • 未提供任何匹配时返回空数组而非失败,因此重复选项天然"可选",取值前无需判空。
  • 约束选项{ min, max }控制最少与最多出现次数,例如"恰好 2~4 个文件"。
  • 常与map()搭配:把数组转成Set(去重小写)或 key-value 对象。

源码入口:packages/core/src/modifiers.ts。

6️⃣ map():变换解析结果

map()用映射函数变换解析结果,同时保留原解析逻辑,适合类型转换、格式归一化、派生字段等场景。

const parser = object({ upperName: map(option("-n", "--name", string()), (name) => name.toUpperCase()), tags: map(multiple(option("-t", "--tag", string())), (tags) => new Set(tags.map((tag) => tag.toLowerCase()))), });

关键要点:

  • 变换函数必须返回新值,不能原地修改输入(延迟提示解析时输入可能是共享占位引用,原地修改会污染后续解析)。
  • 支持链式流式写法,如option("--port", integer()).map((v) => v + 1).withDefault(3001),与独立函数写法等价。
  • 常与or()搭配:把每个分支的 flag 映射成字符串标签(map(flag("--verbose"), () => "verbose" as const)),让联合类型更可读。

源码入口:packages/core/src/modifiers.ts。

🔗 典型组合套路:组合子的威力在"套娃"

场景典型组合
子命令 + 全局选项merge(globals, or(cmdA, cmdB, ...))
全部可选的互斥项optional(or(flagA, flagB))
详细度等级(数 flag 次数)optional(map(multiple(flag("--verbose")), (v) => v.length))
重复参数转 Set / 对象map(multiple(option("-t", string())), ...)
条件性选项组merge(withDefault(object({...}), { flag: false }), globalOptions)

组合之后,帮助文本、shell 补全、man 页面都由同一个解析器定义生成,无需手工同步维护。

组合子产生的错误信息(如or()的noMatch)同样是结构化 Message:选项名、值、metavar 会在终端中着色高亮,管道或 CI 环境下自动降级为带引号的纯文本,方便脚本消费。更多细节见 docs/concepts/messages.md。

🧭 选型决策流:拿不准时按这个顺序问自己

  1. 想把一堆字段按名字组织成对象 →object()
  2. 要"几个里选一"的互斥模式或子命令 →or()
  3. 想把同一组选项在多处复用 →merge()
  4. 某字段允许不出现 →optional()
  5. 某参数可以出现多次 →multiple()
  6. 想在解析后变换值 →map()

如果结果类型"长得不对",先想"少套了哪个组合子",而不是重写整个解析器——这正是组合式解析器"复杂行为由简单积木组合"的核心思想。

📚 参考资料

  • 构造组合子官方文档:docs/concepts/constructs.md
  • 修饰组合子官方文档:docs/concepts/modifiers.md
  • 核心实现源码:packages/core/src/constructs.ts、packages/core/src/modifiers.ts
  • 可运行模式示例目录:examples/patterns/,推荐从 conditional-options.ts、dependent-options.ts、verbosity-levels.ts 入手

【免费下载链接】optique

Type-safe combinatorial CLI parser for TypeScript

项目地址:https://gitcode.com/gh_mirrors/op/optique
点击查看免费下载

相关推荐

上一篇:Bili2text终极指南:3步完成B站视频转文字,轻松获取视频字幕内容
下一篇:5步搞定bili2text安装错误:从零到完美运行的全流程指南 🎯

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 4:07:54

Google Gemma-4-26B-A4B-it-GGUF硬件需求分析:从8GB到50GB显存配置方案

Google Gemma-4-26B-A4B-it-GGUF硬件需求分析&#xff1a;从8GB到50GB显存配置方案 Google Gemma-4-26B-A4B-it-GGUF是由Google开发的大型语言模型的量化版本&#xff0c;基于Gemma-4-26B-A4B-it基础模型通过llama.cpp量化而成。本文将详细分析不同量化版本的硬件需求&#xf…

作者头像 李华