ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

177、【Agent】【OpenCode】TuiThreadCmd(Argv 自动推断)

177、【Agent】【OpenCode】TuiThreadCmd(Argv 自动推断) 【声明】本博客所有内容均为个人业余时间创作所述技术案例均来自公开开源项目如GithubApache基金会不涉及任何企业机密或未公开技术如有侵权请联系删除标题177、【Agent】【OpenCode】TuiThreadCmdArgv 自动推断背景上篇 blog【Agent】【OpenCode】TuiThreadCmdbuilder 泛型分析了模板里的 T 和 UTypeScript 有泛型类型推断Generic Type Inference所以完全不需要手动传入 T 和 U并分析了 TS 是如何推断的cmd 不改变运行时行为只在类型层面做了一次透传增强而所有具体类型都由 TS 从实际代码中自动提取接着分析了cmd.builder的类型模板并重点分析了 CommandBuilder 模板里面出现的 Argv 模板Argv 是 yargs 的核心类型它本质上是一个双重身份的类型既是用来配置选项的工具也是最终解析出来的参数对象T 就是随着每次.option() / .positional()调用不断累积增长的参数类型下面继续分析OpenCode下面继续说下这里的 Argv从这里可以看出来Argv 类型的 options 方法返回的还是 Argv答案直接写在方法的返回值类型注解上。optionKextendsstring,OextendsOptions(key:K,opts:O):ArgvT{[keyinK]:InferOptionTypeO};// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// 这里冒号后面的就是返回值类型拆解来看部分内容含义方法名option(...)配置一个选项参数key: K, opts: O选项名和配置返回值: ArgvT {...}返回一个新的Argv这里关键点在于返回值仍然是Argv...只是泛型参数从 T 变成了T { [key in K]: ... }即 T 加上新选项的类型。这就是链式调用能成立的根本原因因为每次调用.option()都返回 Argv所以下一次调用仍然是在一个 Argv 对象上进行的yargs.option(model,{type:string})// 返回 Argv{ model?: string }.option(continue,{type:boolean})// ← 能在上面继续调因为上一步返回的还是 Argv.positional(project,{type:string})// ← 同理还是 Argv如果某一步返回的不是 Argv比如返回了void链条就断了// ❌ 假设 option 返回 voidyargs.option(model,{...}).option(continue,{...})// ^^^^^^ TS 报错void 上没有 option 方法一句话总结“返回 Argv” 是直接声明在方法签名的返回值类型位置上的。yargs 的每一个配置方法 option、positional、strict、help...都遵循同样的模式接收ArgvT返回ArgvT NewStuff这就是链式调用和类型累积能同时工作的基础。再说下这里的 yargs这里的 yargs 就是 builder 函数的形参parameter它没有变量定义其类型是ArgvT下面从两个层面分析类型层面它是ArgvT在CommandBuilderT, U的定义中((args:ArgvT)ArgvU)// ^^^^^^^^^^^^// 这就是 yargs 参数的类型声明当写builder: (yargs) ...时TS 自动将 yargs 推断为ArgvT其中 T 是从上游全局 yargs 实例或父级命令传递下来的基础参数类型。运行时层面它是 yargs 传入的构建器实例当 yargs 执行命令时它会主动调用 builder 函数并把当前的yargs 构建器实例作为第一个参数传进来// yargs 内部伪代码简化if(command.buildertypeofcommand.builderfunction){// 这里yargs 把自己传给了你的 builderconstconfiguredYargscommand.builder(currentYargsInstance);}所以 yargs 这个变量名只是个形参名叫什么都行// 以下三种写法完全等价builder:(yargs)yargs.option(model,{...})builder:(argv)argv.option(model,{...})builder:(y)y.option(model,{...})串联起来看完整流转全局 yargs 实例携带 T │ ▼ yargs 调用 builder把自己作为参数传入 builder:(yargs: ArgvT)... │ ▼ 在 yargs 上链式调用 .option()/ .positional()│ 每次调用返回新的 ArgvTNewStuff▼ 最终返回 ArgvU← UT{model, continue, project,...}│ ▼ yargs 拿到返回值用 U 来约束 handler 的 argv handler:(argv: ArgumentsU)...一句话总结builder 里的 yargs 是 yargs 框架在执行时主动注入的当前构建器实例。它的类型是ArgvT在这个实例上做的所有.option()配置既改变了运行时的解析行为也同时累积出了最终的参数类型 U。OK本篇先到这里如有疑问欢迎评论区留言讨论祝各位功力大涨技术更上一层楼更多内容见下篇 blog【Agent】【OpenCode】TuiThreadCmdU包含T
返回列表