Escribir documentación para un proyecto TypeScript: nivel avanzado
\n\nLa documentación de calidad no es solo una descripción de funciones, sino una herramienta poderosa que transforma el código en un producto comprensible para el equipo y los usuarios. En TypeScript, gracias a su estricto sistema de tipos, la documentación se vuelve aún más valiosa: no solo explica la lógica, sino que también sirve como fuente de verdad sobre la estructura de datos. A nivel avanzado, la documentación va más allá de los comentarios e incluye generación automática, soporte para tipos complejos e integración con herramientas de desarrollo. En este artículo, analizaremos cómo crear documentación para proyectos TypeScript utilizando enfoques y herramientas modernas.
\n\n1. Uso avanzado de JSDoc y TypeDoc
\n\nJSDoc es un estándar de anotaciones que TypeScript soporta excelentemente. A nivel avanzado, es importante no solo describir parámetros, sino utilizar todas las capacidades del sistema de etiquetas.
\n\n1.1. Etiquetas para tipos complejos
\n\nUse @template para describir genéricos, @typeParam para especificar parámetros de tipo y @callback para definir firmas de funciones callback.
/**\n * Función universal para obtener un valor del almacenamiento.\n *\n * @template T - Tipo del valor devuelto.\n * @param key - Clave para la búsqueda.\n * @returns Valor de tipo T o undefined si la clave no se encuentra.\n */\nfunction getValue<T>(key: string): T | undefined {\n // implementación\n}\n\n/**\n * @callback FetchCallback\n * @param data - Datos obtenidos.\n * @param error - Error, si ocurrió.\n * @returns void\n */\ntype FetchCallback<T> = (data: T, error?: Error) => void;\n\n\n1.2. Documentación de sobrecargas de funciones
\n\nTypeScript permite sobrecargar funciones. En la documentación, cada sobrecarga debe describirse por separado.
\n\n/**\n * Crea una cadena a partir de números.\n * @param a - Primer número.\n * @param b - Segundo número.\n * @returns Cadena que combina los números.\n */\nfunction combine(a: number, b: number): string;\n/**\n * Crea una cadena a partir de cadenas.\n * @param a - Primera cadena.\n * @param b - Segunda cadena.\n * @returns Cadena combinada.\n */\nfunction combine(a: string, b: string): string;\nfunction combine(a: any, b: any): string {\n return `${a}${b}`;\n}\n\n\n1.3. Modificadores personalizados de TypeDoc
\n\nTypeDoc (el generador principal para TypeScript) admite etiquetas personalizadas que se pueden configurar a través del archivo de configuración typedoc.json.
// typedoc.json\n{\n "blockTags": ["@example", "@since", "@deprecated"],\n "modifierTags": ["@internal", "@public", "@experimental"]\n}\n\n\nEjemplo de uso de una etiqueta personalizada:
\n\n/**\n * Realiza una solicitud HTTP.\n *\n * @since 2.1.0\n * @experimental - La API puede cambiar en el futuro.\n * @example\n * ```typescript\n * const result = await httpRequest('https://api.example.com');\n * ```\n */\nasync function httpRequest(url: string): Promise<Response> {\n // ...\n}\n\n\n2. Documentación de tipos e interfaces complejas
\n\nLa documentación avanzada debe describir no solo funciones, sino también estructuras de datos complejas, especialmente si se utilizan en varios lugares.
\n\n2.1. Tipos condicionales y mapeo
\n\nDocumente los tipos condicionales para que el desarrollador entienda cómo funcionan.
\n\n/**\n * Extrae el tipo de los elementos de un array.\n * @template T - Tipo del array.\n */\ntype ArrayElement<T> = T extends (infer U)[] ? U : never;\n\n/**\n * Hace que todas las propiedades de un objeto sean opcionales (Partial).\n * @template T - Tipo de objeto original.\n */\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n\n2.2. Documentación de uniones discriminadas
\n\nLas uniones discriminadas (discriminated unions) son una característica poderosa de TypeScript. En la docum