尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Zod 递归对象 schema 报 ts(7023) 隐式返回 any 的循环类型错误怎么解决?

Zod 递归对象 schema 报 ts(7023) 隐式返回 any 的循环类型错误怎么解决? Zod 递归对象 schema 报 ts(7023) 隐式返回 any 的循环类型错误怎么解决【免费下载链接】zodTypeScript-first schema validation with static type inference项目地址: https://gitcode.com/GitHub_Trending/zo/zod在 Zod 中定义自引用对象 schema例如分类树subcategories字段指向自己的数组时需要在属性上使用 getter 来让 JavaScript 在运行时解析循环引用。但当你在这个 getter 的返回表达式里叠加z.nullable()、z.array()等包装函数时TypeScript 的类型推断有时会失败getter 上报出ts(7023)subactivities implicitly has return type any because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.ts(7023)Zod 官方 API 文档的 Recursive objects / Circularity errors 一节记录了这种错误并给出了直接可用的解决办法给报错的 getter 补一个显式返回类型标注。本文按文档内容复现这个错误、给出修复写法并说明如何确认修复生效。先确认你用的是文档描述的递归对象写法Zod 定义自引用类型的标准方式是在 key 上使用 getterconst Category z.object({ name: z.string(), get subcategories(){ return z.array(Category) } }); type Category z.infertypeof Category; // { name: string; subcategories: Category[] }代码块末尾的z.infer注释来自文档示例展示了该写法推断出的类型形状。文档同时说明了背景限制Due to TypeScript limitations, recursive type inference can be finicky, and it only works in certain scenarios. Some more complicated types may trigger recursive type errors.也就是说这是 TypeScript 递归类型推断自身的限制不是你的 schema 写法错了简单递归如上面的Category可以正常推断更复杂的类型才会触发报错。复现错误哪种写法会报 ts(7023)文档给出的触发示例如下文档示例getter 返回的是z.nullable(z.array(Activity))const Activity z.object({ name: z.string(), get subactivities() { // ^ ❌ subactivities implicitly has return type any because it does not // have a return type annotation and is referenced directly or indirectly // in one of its return expressions.ts(7023) return z.nullable(z.array(Activity)); }, });报错出现在 getter 声明处指向subactivities这个属性它没有返回类型标注而它的返回表达式又直接或间接引用了自身TypeScript 无法在检查和推断之间完成递归解析于是把它标记为隐式any。修复方法给报错的 getter 补返回类型标注文档明确给出的解法是In these cases, you can resolve the error with a type annotation on the offending getter.对应修复后的完整写法文档示例const Activity z.object({ name: z.string(), get subactivities(): z.ZodNullablez.ZodArraytypeof Activity { return z.nullable(z.array(Activity)); }, });对照这两段代码可以看出标注的构成z.ZodNullable对应返回表达式里的z.nullable()z.ZodArray对应z.array()最内层是自引用 schema 的typeof Activity。如果你的 getter 返回的是别的组合例如其他包装函数按同样的思路把返回表达式中用到的 schema 类名写进标注即可。这个改动只作用于类型层面getter 的运行时实现return z.nullable(z.array(Activity));一行未动schema 行为不变只是让 TypeScript 不再需要对该 getter 做递归推断。验证修复结果这是编译期错误验证方式就是看类型检查是否通过按上面的写法给报错的 getter 加上返回类型标注后重新运行项目的 TypeScript 检查例如你平时用的tsc或 IDE 的即时代码检查该 getter 上的ts(7023)错误应当消失——文档原话是这个标注 resolve the error。用z.infer查看推断结果是否如预期例如文档中Category的例子推断为{ name: string; subcategories: Category[] }文档示例。对修复后的Activity同样可以写type Activity z.infertypeof Activity来检查字段类型是否符合你的数据结构。如果加标注后仍有其他类型错误说明你的 schema 触发了文档所说的 certain scenarios 之外的更复杂情况回到 Circularity errors 一节核对你当前写法是否与示例属于同一模式。限制与边界文档没有给出哪些类型一定会触发 ts(7023)的完整清单只说明递归类型推断依赖 TypeScript 的有限支持only works in certain scenarios。所以处理路径是先按不加标注的 getter 写法定义 schema报错了再按本文方式补标注。并非所有递归都要标注。文档同时给出了互相递归mutually recursive types的可工作示例两个 getter 均未标注返回类型const User z.object({ email: z.email(), get posts(){ return z.array(Post) } }); const Post z.object({ title: z.string(), get author(){ return User } });只有实际报错时才需要对offending getter即报错指向的那个 getter补标注。本方案解决的是类型层面的循环推断错误递归输入数据cyclical inputs的解析是另一项能力Zod 开箱即用Zod Mini 则需要注册 memoizer与本错误无关。【免费下载链接】zodTypeScript-first schema validation with static type inference项目地址: https://gitcode.com/GitHub_Trending/zo/zod创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表