ARTICLE DETAIL

资讯详情

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

TypeSpec 2024 年 1 月版本发布说明:命名模板参数、@encodedName 与编译器生态更新

TypeSpec 2024 年 1 月版本发布说明:命名模板参数、@encodedName 与编译器生态更新 TypeSpec 2024 年 1 月版本发布说明命名模板参数、encodedName 与编译器生态更新【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec本文是 TypeSpec 仓库 website/src/content/docs/release-notes/release-2024-01-23.md 的技术解读。2024 年 1 月 23 日的这个版本是 TypeSpec 发展史上的一个重要里程碑编译器引入了命名模板参数与模板参数约束两个新的语言特性新增了encodedName装饰器与getEncodedName访问器tsp init获得了--template选项并新增了 emitter 与 library 两套脚手架模板同时该版本移除了对 Node 16 的支持最低要求 Node 18playground 的样式导入方式也发生了破坏性变更。阅读本文你将掌握这些新特性的使用方式、底层实现原理、破坏性变更的迁移要点以及它们在编译器、openapi3、playground、bundler 各包中的实际落点。版本概览与破坏性变更提醒本版本发布前官方在文档开头即标注了caution 警告本次发布包含破坏性变更breaking changes。具体涉及两类运行环境要求提升TypeSpec 彻底放弃对 Node.js 16 的支持最小版本要求提升到Node 18因为 Node 16 已不再被官方维护playground 样式导入方式变更样式必须单独通过import typespec/playground/styles.css;导入。任何正在升级依赖的项目都需要先确认自己的 Node 版本并调整 playground 相关代码否则可能直接报错或无法构建。编译器typespec/compiler新特性本版本编译器包的新特性最为密集几乎都围绕语言能力、模板体系和初始化脚手架展开下面逐一展开。命名模板参数位置参数之外的新选择TypeSpec 模板此前只能按位置实例化即按声明顺序传入类型实参。本版本新增了命名模板参数named template arguments能力模板既可以按位置实例化也可以按名称实例化。例如// 位置实例化原有方式 alias Foo Barint32, string; // 命名实例化新增方式 alias Foo Barname: string, value: int32;命名实参的引入意味着模板参数在声明处的名称从此成为公共 API 的一部分。为了保证命名实例化的可用性与可读性官方在此版本中统一规范化了所有 TypeSpec 库的模板参数命名原发布说明中特别注明 All TypeSpec libraries normalized Template parameter names in anticipation of this change并直接重命名了既有模板参数。因此如果你的代码库中依赖了某个库模板参数的具体名称或通过具名方式引用它们升级时需要注意同步更新。从编译器源码看模板参数的类型检查与实例化逻辑集中在 packages/compiler/src/core/checker.ts而模板相关测试覆盖在 packages/compiler/test/checker/templates.test.ts读者可以通过这些文件深入理解命名实参的解析与校验过程。模板参数约束用另一个模板参数做约束配合命名模板参数编译器还新增了一个语言特性允许使用另一个模板参数作为约束条件。典型写法如下model FooA, B extends A { b: B; }这里B extends A表示B必须是A或其子类型从而在模板层面建立参数之间的依赖关系。这种写法让模板可以表达更精确的泛型关系例如要求某个集合的键类型与值类型之间存在继承关系或者在库 API 中强制调用者传入相互关联的类型组合。tsp init 新增 --template 选项tsp init命令行新增了--template选项允许用户在模板列表中直接指定要使用的模板名称而无需再通过交互式菜单选择。查看当前仓库的 CLI 定义packages/compiler/src/core/cli/cli.tstsp init命令现在支持以下完整参数集选项类型说明[templatesUrl]位置参数string初始化模板的 URL。官方警告下载或使用不受信任的模板可能包含恶意包需谨慎并核实来源--templatestring要使用的模板名称--no-prompt/-yboolean自动接受所有提示除非某提示必填且无默认值默认false--project-namestring项目名称--arg/--argsarray用于配置的键值参数--template-emittersarray要包含在项目中的 emitters模板未指定的 emitters 会被忽略默认 emitters 始终包含--output-dirstring生成产物的输出路径必须已存在例如非交互式地基于 emitter 模板创建项目tsp init --template emitter-ts --project-name my-emitter --no-prompt新增 emitter-ts 与 library-ts 两个初始化模板与--template配套本版本新增了两个官方脚手架模板emitter-ts用于创建一个新的 TypeSpec **emitter代码生成器**项目library-ts用于创建一个新的 TypeSpec **库library**项目。在仓库中这两个模板的完整文件清单定义于 packages/compiler/templates/scaffolding.json其实际模板文件位于 packages/compiler/templates/emitter-ts 与 packages/compiler/templates/library-ts 目录。以 emitter-ts 为例模板包含package.json、tsconfig.json、src/lib.ts、src/emitter.ts、src/index.ts以及配套测试文件test/hello.test.ts等library-ts 模板则额外包含lib/decorators.tsp、lib/main.tsp、src/linter.ts、src/rules/no-interfaces.rule.ts等库开发所需的结构。这意味着从本版本开始开发一个 TypeSpec emitter 或 library 的标准姿势是tsp init emitter-ts # 或 tsp init library-ts新增 encodedName 装饰器与 getEncodedName 访问器本版本为编译器新增了encodedName装饰器和配套的getEncodedName访问器用于解决同一类型在不同序列化格式MIME 类型下需要不同名字的问题。以官方标准库文档packages/compiler/lib/std/decorators.tsp中的示例为例model Certificate { encodedName(application/json, exp) encodedName(application/xml, expiry) expireAt: int32; }序列化为application/json时expireAt属性输出为exp序列化为application/xml时输出为expiry其他 MIME 类型下则保留原始名称expireAt。encodedName的签名是encodedName(target, mimeType, name)其中mimeType必须是不带后缀的已知 MIME 类型不允许出现json之类的 subtype 后缀。若传入带后缀的类型编译器会报错。这一点在getEncodedName的实现中体现得很清楚——packages/compiler/src/lib/encoded-names.ts 会通过parseMimeType解析并剥离后缀并利用createStateSymbol(encodedName)建立类型到MIME 类型, 名称映射的 state。此外编译器还提供了resolveEncodedName(program, target, mimeType)辅助函数见 packages/compiler/src/lib/encoded-names.ts如果指定 MIME 类型下有encodedName声明则返回该名字否则回退到类型自身的名字。并且实现了冲突校验validateEncodedNamesConflicts既会检查编码名是否与模型/枚举/联合中已有的成员名冲突也会检查同一 MIME 类型下两个编码名是否映射到同一个名字诊断码encoded-name-conflict。需要特别注意的是encodedName只负责声明“编码后的名字”序列化时具体是否使用它取决于下游 emitter。例如 openapi3 emitter 在本版本中同步增加了对encodedName的支持。字节编码与库声明中的 State 符号本版本还有两项对库开发者友好的增强bytes 编码支持bytes类型被纳入通用 encode 类型体系即可以使用通用编码机制来控制bytes的序列化形式库声明支持 State 符号允许在库声明library declaration中集中定义库所用的 state 符号为库的内部状态管理提供了统一入口避免分散定义。另外init 模板中还新增了一个修改命名大小写casing的辅助函数方便脚手架在生成代码时统一命名规范。相关 Bug 修复提升了语言服务器的性能进而改善了语法高亮等 IDE 功能的响应速度修复了 Windows 上超过 256 个字符的长路径的文件解析问题修复了使用未指定compilerVersion的模板执行tsp init时的告警误报。openapi3encodedName 支持落地typespec/openapi3包在本版本中新增了对encodedName装饰器的支持。查看源码openapi3 的 schema 发射逻辑packages/openapi3/src/schema-emitter.ts会调用resolveEncodedName(program, prop, contentType)根据当前输出内容的 MIME 类型content type决定属性在 OpenAPI schema 中的名字packages/openapi3/src/xml-module.ts 中也引入了该能力。实际效果当你的 TypeSpec 模型通过encodedName声明了application/json与application/xml两套名字且 openapi3 emitter 分别生成 JSON 与 XML 相关描述时属性名会按 MIME 类型自动切换从而让一份模型定义能够精确适配多种序列化格式的命名约定。bundlertypes 入口、独立 CLI 与包清单typespec/bundler本版本有三项变化支持exports下的types入口取代旧的typesVersions写法所有 TypeSpec 库都已切换到这种新的包定义风格新增了typespec-bundler的CLI 入口可以直接用命令行完成打包打包产物会暴露 bundle manifest其中包含相对 importmap、包名和版本信息方便运行时按需加载与调试。playground编辑器体验升级typespec/playground在交互体验上有一批改进命令栏新增格式化按钮standalone 模式在保存后显示通知编辑区与输出区支持可拖拽调整大小的面板resizable panes支持通过Footer/FooterItem组件自定义页脚通过createBrowserHost可配置库加载方式使用系统importmap或 es-module-shim 的importmap-shim这是为弥补浏览器对外部 source map 支持不足而引入的新增skipBundleLibraries选项允许使用者自行管理importmap或决定是否把本地库打进 bundle错误与警告被收敛到编辑器底部的专用可展开横幅expandable banner移除了githubIssueUrl链接改为onFileBug回调让宿主应用自行决定“报 bug”的行为standalone 模式支持加载回退loading fallback。同时修复了两个问题程序查看器program viewer现在会遵循颜色主题CSS 导出在原有style.css之外补充了styles.css两者均保留以兼容旧代码但推荐使用styles.css。http 与 restpath 自定义名修复本版本修复了path自定义名称相关的一组路由问题typespec/http确保path的自定义名称被正确遵守当路径参数不是字母数字例如path中提供了不同的名称或属性名本身不是合法标识符时也能正确生成路径typespec/rest修复了在构建路由时对自定义path名称的处理。此前这类场景可能产生错误的 URL 路径升级后路由生成行为将更符合预期。弃用项$lib 上的 linter 属性库声明相关的弃用项是本次唯一的 Deprecation弃用$lib上的linter属性推荐改为导出独立的$linter变量。官方给出的理由是为了避免在$lib中引用 linter 规则造成的循环引用。迁移方式将 linter 规则从$lib对象中移出改在库模块顶层导出$linter即可。破坏性变更迁移清单升级到本版本时请逐一核对以下变更Node 版本最低要求从 Node 16 提升到Node 18请先升级运行环境playground 样式样式不再随包自动注入需显式import typespec/playground/styles.css;模板参数命名各库的模板参数已规范化/重命名若代码中按名称引用模板参数需同步更新$lib.linter改为导出$linter变量避免循环引用playground APIgithubIssueUrl已移除改由onFileBug回调接管样式导出推荐styles.css打包风格若自研库仍使用typesVersions建议迁移到exports下的types入口。延伸阅读编译器语言特性与模板系统与模板测试用例encodedName 实现及标准库声明openapi3 的 encodedName 应用tsp init CLI 参数定义与脚手架模板清单emitter-ts 模板与library-ts 模板【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表