- El PR de refactorización del repositorio de Svelte en 2023 llamó la atención de los escépticos de TypeScript al cambiar a código basado en JSDoc
- Desde Svelte explicaron que esto no era una postura anti-TypeScript, sino parte de una dependencia continua de TypeScript
- El artículo enfatiza que JSDoc y TypeScript no deben verse como opuestos, sino que JSDoc en sí forma parte de TypeScript
- TypeScript funciona como motor de IntelliSense, encargado tanto de interpretar comentarios JSDoc como de la autocompletación de código
- JSDoc ofrece la misma capacidad de análisis estático sin etapa de build, y en proyectos modernos de JS cumple en la práctica el mismo papel que TypeScript
El PR de Svelte y el contexto de la polémica
- En mayo de 2023, un PR de refactorización interna del repositorio de Svelte llegó a la portada de Hacker News
- Ese PR cambiaba las declaraciones de tipos de archivos
.ts a comentarios JSDoc en archivos .js
- Algunos interpretaron esto como un rechazo a las ventajas de TypeScript
- El creador de Svelte, Rich Harris, explicó directamente en HN: “esto no es anti-TypeScript”
- También mencionó que el compromiso de Svelte con TypeScript sigue siendo sólido
- Después de este episodio, aparecieron muchos artículos comparando “TypeScript vs JSDoc”, y se extendió la idea de describir JSDoc como “TypeScript sin etapa de build”
El origen y la esencia de TypeScript
- Entre finales de los 2000 y comienzos de los 2010, JavaScript era visto como un lenguaje con carencias en autocompletado y seguridad de tipos
- Los desarrolladores de Microsoft respondían usando ScriptSharp para convertir código C# a JS
- En ese contexto nació TypeScript, que en esencia comenzó como una herramienta de build para mejorar el desarrollo en JS
TypeScript es IntelliSense
- TypeScript no es solo un lenguaje: también cumple el papel de motor de IntelliSense
- Incluso sin usar archivos
.ts, la autocompletación, la información de parámetros y la navegación entre símbolos las provee el servicio de lenguaje de TypeScript
- En la mayoría de los editores, incluso al escribir código JS, el servicio de TypeScript funciona como backend
TypeScript es JSDoc
- El servicio de lenguaje de TypeScript también se usa para interpretar comentarios JSDoc
- En el CHANGELOG de TypeScript aparecen con frecuencia nuevas funciones relacionadas con JSDoc
- Los proyectos basados en JSDoc también pueden configurarse con
tsconfig.json, y con el comando tsc se puede realizar verificación de tipos
- Por eso, un desarrollador que usa JSDoc en realidad ya está usando TypeScript
Experiencia con proyectos basados en JSDoc
- El autor comparte la experiencia de haber reescrito el frontend de un proyecto existente usando anotaciones de tipos con JSDoc
- Salvo por funciones de runtime como los enum, la mayoría de las expresiones de TypeScript pueden hacerse con JSDoc
- Los genéricos tienen una sintaxis algo más compleja, pero llevan a aprovechar más la inferencia de tipos
- En proyectos con JSDoc, al hacer clic en una función se puede ir al código real, lo que mejora la experiencia de desarrollo
- El ecosistema de herramientas de TypeScript también puede reutilizarse en proyectos con JSDoc
- Por ejemplo, librerías que generan tipos desde esquemas OpenAPI o GraphQL también pueden generar tipos en forma de comentarios JSDoc
Conclusión y casos adicionales
- JSDoc no es una alternativa a TypeScript, sino que comparte el mismo sistema de análisis estático
- Permite omitir la etapa de build y aun así ofrecer una estabilidad de tipos equivalente
- Además, se menciona como caso adicional que el proyecto webpack también migró a JSDoc
- Como experto en TypeScript, el autor deja clara su postura: “JSDoc es TypeScript”
1 comentarios
Comentarios en Hacker News
Resume lo que aprendió tras varios años desarrollando y manteniendo software web y de robótica con Python/JavaScript
Los tipos existen aunque no se declaren, y si no se declaran, terminan existiendo solo en tu cabeza
Pero la cabeza es muy volátil y a otras personas les cuesta acceder a lo que hay ahí
Por eso, tipar es una excelente forma de documentación
JSDoc y TypeScript son formatos estándar para expresar tipos, y ambos tienen ventajas y desventajas
Lo importante es definir los tipos de manera consistente y predecible
El type checker es la forma en que la computadora dice: “entonces demuéstralo”
No todos los programas necesitan el mismo nivel de prueba, y exigir pruebas de más puede ser un desperdicio
Por eso prefiero lenguajes que permitan “demostrar” solo lo necesario
Trabajando aprendí muy claramente que “otras personas” también incluye a mi yo del futuro
Rust permite relajar restricciones con cosas como unsafe, Arc, clone, pero a cambio te obliga a elegir claramente qué restricciones no quedaron demostradas
En cambio, en lenguajes donde “no hace falta demostrarlo”, es difícil saber qué enfoque tomó internamente
El enfoque de Rust puede usarse de forma flexible al principio, como Python, pero después resulta mucho más ventajoso en legibilidad y escalabilidad
No era un intento de defender una herramienta en particular, solo quería enfatizar que ambos son formas de expresar un sistema de tipos
Los lenguajes con tipado estático eran mucho más fáciles de manejar en proyectos en equipo, y todavía hoy prefiero tipos estáticos siempre que puedo
Si ves las definiciones de tipos de TypeScript añadidas después a librerías existentes de JS, la complejidad es enorme
Incluso un solo tipo incorrecto puede romper toda la compilación
Al final, los lenguajes dinámicos hay que usarlos haciéndose cargo uno mismo
Me gusta todo lo que se puede hacer en JavaScript sin build step
La combinación de HTML/CSS moderno, Web Components y JSDoc está subestimada
No es para todo el mundo, pero me parece un candidato suficientemente moderno para un stack frontend
Además, funciones como HMR han reducido bastante el costo del build step
Siempre pasa por Vite o Webpack, así que no siento en la práctica las ventajas del JS sin build
Ojalá hubiera una forma más sencilla de hacer componentes complejos
Seguir solicitudes de red, saltar directo al código fuente, poner breakpoints y demás hace que depurar sea mucho más intuitivo
A medida que crece la escala, ese entorno ayuda muchísimo
En la época en que los SPA estaban de moda, JSDoc era el salvavidas para gestionar tipos
Después apareció Google Closure Compiler y ofreció seguridad de tipos basada en JSDoc, y TypeScript pasó a soportar (TS)JSDoc junto con su propia sintaxis
La comunidad al final eligió TypeScript y Closure Compiler desapareció
Por eso, (TS)JSDoc quedó como un vestigio de la época en que MS competía con Google
Ahora TS ofrece muchísimas más funciones: genéricos, Enum, utility types, type tests de Vitest, type guards, etc.
Yo uso TS y JSDoc juntos — TS para el código, JSDoc para la documentación (@link, @see, @deprecated, @example, etc.)
Genéricos, utility types, type guards, parsing de expresiones regulares y la mayoría de las funciones de TS también pueden aprovecharse en JSDoc
En un proyecto personal llegué a implementarlo todo con JSDoc, incluyendo genéricos
Decir que (TS)JSDoc es una reliquia del pasado es información incorrecta, así que no debería difundirse sin verificarla
Se dice que hay muchos tipos que no pueden expresarse con JSDoc, pero ojalá hubiera existido un enfoque de lenguaje completo como Flow
TypeScript también podría haber ido por ahí y no sé por qué no lo hizo
Yo también pensaba eso antes, pero cambié de opinión al refactorizar un proyecto a JSDoc
En JSDoc también se pueden definir slots genéricos con
@templateEjemplo:
Enlace relacionado
Los paquetes escritos con JSDoc ofrecen una buena experiencia de desarrollo porque al hacer CMD/CTRL clic puedes ir al código real
Hace 5 años, en un meetup, un expositor dijo que “si no te gusta TypeScript, JSDoc es una alternativa”
Yo le expliqué que al final ambos son TypeScript, pero mi jefe no me creyó
JSDoc y TS expresan explícitamente los tipos, pero la sintaxis de TS es mucho más potente
Aun así, para quienes quieren mantener un entorno JS y aprovechar las herramientas de tipos, JSDoc es una buena opción
Como contraargumento, JSDoc no es TypeScript
Los tipos definidos con
@typedefse exportan automáticamente y no hay forma de controlarloIssue relacionado
Por eso, al desarrollar librerías, IntelliSense quedaba expuesto de forma desordenada, lo que resultaba molesto
Puedes copiar el archivo “my-component.js” tal cual y funciona sin build
Pero en proyectos grandes prefiero la sintaxis de TS
@importse resuelve casi todo en la mayoría de los casosEstoy de acuerdo con la idea de que “JSDoc no es una alternativa a TypeScript”
JSDoc también proporciona análisis estático, pero sin build step
Consulta la documentación oficial de Node
Pero TypeScript basado en JSDoc también funciona en el navegador
Personalmente prefiero la legibilidad de la sintaxis de TS, y con herramientas como
swcla eliminación de tipos es lo bastante rápidaLa razón por la que TypeScript derrotó a otras alternativas fue que siguió siendo un type checker en vez de convertirse en un lenguaje nuevo
Al principio su dirección fue algo inestable, pero la corrigieron a tiempo, y hoy en día en la mayoría del código ni siquiera se usan mucho los enums
En VSCode, si activas la opción “TypeScript: Prefer Go To Source Definition”, puedes ir directamente al código fuente real
Además, si agregas
declarationMap: trueentsconfig, funciona con más precisiónCasi siempre prefiero que cmd+click me lleve al código fuente