Tengo la siguiente estructura de proyecto:
api/ users/ users.d.js contexts/ users/ users.d.js utils/ users/ users.d.jsEn utils/users/users.d.js estoy definiendo los tipos que son reutilizables en todo el sistema.
Por ejemplo, el siguiente tipo:
/** * Represents a User. * * @typedef {object} User * @property {string} id - Unique identifier. * … * @property {Date} birthday - Birthday. */Esto es genial, ahora puedo reutilizarlo en mi módulo index.js de la siguiente manera:
import “./utils/users/users.d”; /** * … * @param {User} user - The profile owner. */ function navigateToUserProfile(user) { … }¡Y eso funciona bien! Mi editor de código detecta el tipo y la documentación se puede generar automáticamente sin problemas :)
Pero... ¿y si api/users/users.d.js requiere esa definición de tipo global?
Por ejemplo, qué pasa si en ese módulo tengo la siguiente definición:
/** * @typedef {object} EditProfileInterface * * @property {User} newUserData - The new user data. * … */Para reutilizar la definición global, necesitaría importar el módulo de utilidad ( utils/users/users.d.js ) en el módulo de "definiciones de tipo local" ( api/users/users.d.js ).
Okey… entonces, solo hagamos:
// this code is inside api/users/users.d.js import “../../utils/users/users.d”;como hicimos dentro de index.js .
Aquí es donde viene mi problema. Después de hacer esto, JSDOC ya no puede generar la documentación correctamente. Mueve las definiciones de tipo de api/users/users.d.js a la sección global de la documentación.
Además, si hago // @ts-check dentro de un módulo que importa api/users/users.d.js , aparece el error Cannot find name 'EditProfileInterface' (tipo no resuelto). Esto está dificultando mucho la reutilización de tipos… parece que no hay más opciones que duplicar las definiciones entre módulos (?)
¿Alguna sugerencia o solución? ¿Simplemente no debería preocuparme por duplicar definiciones de tipo entre diferentes módulos?
El truco consiste en configurar JSDoc para admitir el modo typescript .
1- Cree un archivo jsconfig.json para activar ts-check en todo su proyecto:
Este es el código que uso:
{ "compilerOptions": { "baseUrl": ".", "module": "commonjs", "target": "es2021", "jsx": "react-native", "checkJs": true, <--- ACTIVES the @ts-check directive in every single module of your project in order to avoid bugs :) }, "include": ["app/**/*.d.js", "app/**/*.js", "app/**/*.cjs", "app/**/*.mjs", "app/**/*.jsx"], "exclude": ["node_modules", "./functions/", "./docs"] }Si obtiene un error de pelusa, simplemente vuelva a abrir VSCode.
2- Instala esta dependencia de desarrollo: jsdoc-tsimport-plugin
yarn add --dev jsdoc-tsimport-plugin3- En su archivo de configuración jsdoc, agregue el complemento instalado:
module.exports = { plugins: [ "plugins/markdown", "node_modules/better-docs/category", "node_modules/jsdoc-tsimport-plugin/index.js", <------- THIS! ], source: { include: [ "Main.jsx", "app/", "functions/", "shared/", ], includePattern: ".+\\.(js(doc|x)?|(m|c)js)$", excludePattern: "(node_modules/|docs)", }, sourceType: "module", tags: { allowUnknownTags: true, dictionaries: ["jsdoc", "closure"], }, ...4- En su archivo de configuración de eslint, agregue la siguiente configuración:
extends: [ "eslint:recommended", "airbnb", "prettier", "plugin:react/recommended", "plugin:react-native/all", "plugin:jsx-a11y/recommended", "plugin:react-hooks/recommended", "plugin:import/recommended", "plugin:flowtype/recommended", "plugin:jsdoc/recommended", ], settings: { jsdoc: { mode: "typescript", <--- THIS! }, }, rules: { ...AHORA PUEDES UTILIZAR LA SINTAXIS DE TYPESCRIPT CON JSDOC
Por ejemplo, en esta estructura de proyecto:
shared/ types.d.js api/ users/ users.d.jsPuede definir un tipo en sus tipos globales (dentro de la carpeta compartida):
/** * Some description for the type definition. * * @typedef SomeGlobalType * @property {string} [text="Hello world"] - Description for the property. */ Y luego, simplemente impórtalo dentro de api/users/users.d.js , así:
/** * @typedef User * @property {import("../../shared/types.d").SomeGlobalType} tricky - HEHE */Eso es todo ;)