数字误识别为字符,字符串误识别为数组,Promise取值无需await。如果每种类型都在TypeScript中正确定义,并且出现漂亮的编辑提示,这些问题将无法解决。但是在写命令行工具的时候,定义某种类型的option时,需要传入.option("-d,--dev")等参数,并标记类型如{dev:boolean}。两个地方需要手动同步。又麻烦又容易出错,怎么办?TypeScript早在4.1就已经能够设计和分析字符串生成的类型。现在,通过@commander-js/extra-typings,可以自动获取字符串中设计的命令结构。从“@commander-js/extra-typings”导入{程序};程序.argument("").argument("[outdir]").option("-c,--camel-case")。action((input,outputDir,options)=>{//输入是字符串//outputDir是字符串|undefined//options是{camelCase?:true|undefined}});本文介绍@commander-js/extra-typings的使用关键技术。必选/可选,单个/多个必选/可选参数通常采用/[xxx]的形式,其中xxx为参数名称。当参数名以...结尾时,表示该参数可以包含多个值。对于这样的字符串,使用extends关键字设计相应类型的条件。//S使用""得到true//S使用"[arg]"得到falsetypeIsRequired=Sextends`<${string}>`?true:false;//S将“”设为真//S将“”设为假类型IsVariadic=Sextends`${string}...${string}`?真假;optionnameoptionname通常有缩写,例如-r可能表示--recursive。通常作为命令行选项使用——以小写字母命名方式,代码中经常使用驼峰命名方式。对于使用逗号+空格来前置缩进的选项,可以使用infer关键字递归推断模板文字。//S使用“-o,--option-name”得到“option-name”typeOptionName=Sextends`${string},${inferR}`?OptionName//移除逗号、空格和之前的内容:Sextends`-${inferR}`?OptionName//去掉开头的“-”:S;将破折号-转换为驼峰式大小写,可以与大写结合使用。//S使用“option-name”得到“optionName”typeCamelCase=Sextends`${inferW}-${inferR}`?驼峰式<`${W}${大写}`>:S;可变长度参数是具有可变长度参数的函数。可以通过扩展类型元组来定义参数。输入参数=[布尔值、字符串、数字];输入VarArgFunc=(...args:Args)=>void;constfunc:VarArgFunc=(arg1,arg2,arg3)=>{//arg1是布尔值//arg2是字符串//arg3是数字};类型元组可以存储在类参数中,新元素也可以通过扩展运算符组合....declareclassFoo{concat(arg:T):Foo<[...参数,T]>;run(fn:(...args:Args)=>void):void;}constfoo=newFoo().concat(1).concat("str").concat(true);foo.run((arg1,arg2,arg3)=>{//arg1是数字//arg2是字符串//arg3是布尔值});限制实施@commander-js/extra-typings的最大障碍在于保留此信息。在变长参数部分,concat每增加一次信息,都需要返回一个新的实例。是否可以使用&或mixin等其他技术将其结合起来?目前,实际测量结果并不理想。TS在这种实测中非常容易报错或者卡住。没有卡住的时候会提示TS校验陷入死循环。.相关文档可以在原始实现PR#1758·tj/commander.js中找到。这样的限制也体现在@commander-js/extra-typings的引入上。由于在类型定义中每次都返回一个新的实例,因此可能很难获得很多良好的类型支持;每个操作都需要对前一个操作的返回值执行,以使用正确和完整的类型信息。