如何在JSDoc中推断Zod类型(不使用TypeScript)。

huangapple go评论70阅读模式
英文:

How to infer Zod type in JSDoc (without TypeScript)

问题

以下是翻译好的部分:

假设我在JavaScript中有以下模式:

import {z} from "zod";
let personSchema = z.object({
  name: z.string(),
  id: z.number()
});

现在我想在其他地方使用该类型:

/** 
* @param {{name:string, id:number}} person 
* 但应该改成类似这样:
* @param {???(typeof z)["infer"]<typeof personSchema>???} person 
*/
function (person) {
 person.name; // 自动完成和VSCode的linting应该在这里起作用
 // 做一些事情
}

当然,在TypeScript中这将很容易,但由于项目不允许TypeScript,我正在尝试使用JSDoc。

英文:

Suppose I have the schema in javascript:

import {z} from "zod";
let personSchema = z.object({
  name: z.string(),
  id: z.number()
});

now I want to use the type somewhere else:

/** 
* @param {{name:string, id:number}} person 
* but should instead be something like this?:
* @param {???(typeof z)["infer"]<typeof personSchema>???} person 
*/
function (person) {
 person.name; // autocompletions and vscode linting should work here
 // do stuff
}

Of course this would be easy in typescript, but I'm trying to use JSDOC since the project doesn't allow TypeScript.

答案1

得分: 2

以下是翻译好的部分:

import {z} from "zod";

/** 
* @typedef {z.infer<typeof PersonSchema>} Person
*/ 
let PersonSchema = z.object({
  name: z.string(),
  id: z.number()
});

/** 
* @param {Person} person
*/ 
function (person) {
 person.name; // autocompletions and vscode linting should work here
 // do stuff
}
英文:

Here's a way to use z.infer to define a type using jsdoc (similar to the way you would do so in Typescript), then use the new type in the function annotation:

import {z} from &quot;zod&quot;;

/** 
* @typedef {z.infer&lt;typeof PersonSchema&gt;} Person
*/ 
let PersonSchema = z.object({
  name: z.string(),
  id: z.number()
});

/** 
* @param {Person} person
*/ 
function (person) {
 person.name; // autocompletions and vscode linting should work here
 // do stuff
}

答案2

得分: 1

这个有效:

/** 
* @param {ReturnType<(typeof personSchema)["parse"]>} person
*/ 
function (person) {
 person.name; // 这里应该可以自动完成和VSCode的linting工作
 // 做一些操作
}

虽然这个有效,但我怀疑有更好的解决方案。

英文:

This works:

/** 
* @param {ReturnType&lt;(typeof personSchema)[&quot;parse&quot;]&gt;} person
*/ 
function (person) {
 person.name; // autocompletions and vscode linting should work here
 // do stuff
}

Although this works, I suspect there is a better solution.

答案3

得分: 0

以下是翻译好的内容:

有一种方法可以尝试,那就是利用类型命名空间和值命名空间之间的分离,通过导出模式的类型与模式同名。例如,您可以这样写:

export const personSchema = z.object({ /* ... */ });
// 如果您正在使用 eslint,它可能会在这里抱怨,但您可以忽略
// 重新声明的投诉
export type personSchema = z.infer<typeof personSchema>;

当 TypeScript 从 JSDOC 推断类型时,将导入 personSchema 类型并解析,以便您可以得到正确的值:

/**
 * @param {personSchema} person
 */
function (person) {
  person.name;
};

这将适用于常规的 JS,因为类型不存在,所以只会导入模式,而且对于 TS 也能正常工作,因为它可以区分用作类型的东西和作为值的东西。

英文:

One thing you could try is to take advantage of the separation between the type namespace and the values namespace by exporting the type of the schema with the same name as the schema. For example you could say

export const personSchema = z.object({ /* ... */ });
// If you&#39;re using eslint, it may complain here but you can ignore
// the redeclaration complaint
export type personSchema = z.infer&lt;typeof personSchema&gt;;

When Typescript is working out the types from the JSDOC the personSchema type will be imported and will resolve so you get the correct value with:

/**
 * @param {personSchema} person
 */
function (person) {
  person.name;
};

This will work with regular JS since the types won't exist so only the schema will be imported, and it will also work with TS because it can distinguish between something being used as a type and something that is a value.

huangapple
  • 本文由 发表于 2023年5月29日 09:13:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定