Как вывести тип Zod в JSDoc (без TypeScript)

Предположим, у меня есть схема в javascript:

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

теперь я хочу использовать этот тип где-то еще:

/** 
* @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
}

Конечно, это было бы легко в машинописи, но я пытаюсь использовать JSDOC, так как проект не позволяет использовать TypeScript.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
54
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это работает:

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

Хотя это работает, я подозреваю, что есть лучшее решение.

Следуя вашей подсказке, вы также можете определить тип Person после схемы: @typedef {ReturnType<(typeof personSchema)["parse"]>} Person... затем использовать @param {Person} person в аннотации jsdoc функции.

Duane J 29.05.2023 19:52

Одна вещь, которую вы можете попробовать, — это воспользоваться преимуществом разделения между пространством имен типа и пространством имен значений, экспортируя тип схемы с тем же именем, что и схема. Например, вы могли бы сказать

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

Когда Typescript обрабатывает типы из JSDOC, тип personSchema будет импортирован и разрешен, поэтому вы получите правильное значение с помощью:

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

Это будет работать с обычным JS, поскольку типы не будут существовать, поэтому будет импортирована только схема, и это также будет работать с TS, поскольку он может различать что-то, используемое как тип, и что-то, что является значением.

Разве z.infer<typeof personSchema> не требует шага компиляции машинописного текста?

Duane J 29.05.2023 19:48

Верно. Думаю, я не был уверен, какова точная настройка ОП. Я думал, что он импортирует свою схему из кода TypeScript в JavaScript, но я думаю, что ваша интерпретация, вероятно, верна, и я все равно предпочел бы ваш ответ, поскольку он позволяет избежать перегрузки имени и дает лучшее имя для типа.

Souperman 30.05.2023 02:49
Ответ принят как подходящий

Вот способ использования z.infer для определения типа с помощью jsdoc (аналогично тому, как вы делаете это в Typescript), а затем используйте новый тип в аннотации функции:

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
}

интересно, что z.infer идет в комплекте из импорта. Спасибо!

bristweb 30.05.2023 03:35

Другие вопросы по теме