Hace unos tres años y medio escribí un post sobre TypeScript en el que explicaba por qué su propuesta no me parecía atractiva en ese momento. Recientemente hemos tenido algo de tiempo libre en mi trabajo del Mundo Real™ y hemos podido dedicarnos a analizar unos cuantos lenguajes que podríamos usar en un futuro no muy lejano para desarrollar aplicaciones web. Uno de ellos ha sido TypeScript y creo que es justo, después de aquel post del 2012, dedicarle otro con mi opinión actualizada.
Ya he dicho alguna vez que al elegir un lenguaje de programación influyen factores externos al propio lenguaje. Estos factores están más ligados al contexto en que se va a usar, por lo que en este post se mezclan algunas cosas más objetivas con otras bastante discutibles.
Lo bueno
TypeScript se ha convertido en bastante potente y que empieza a tener personalidad propia. La sensación que transmitía al principio de ser un intento de llevar C# al browser, aunque sigue presente, ya no es tan grande.
En ello ha influido la evolución de Javascript. Como TypeScript siempre ha sido un superconjunto de Javascript, se ha ido compatibilizando con las nuevas construcciones de ECMAScript 2015. Esto facilita el paso desde Javascript “moderno” hacia TypeScript y resulta agradable.
Desde siempre, la gran característica de TypeScript fueron, como no, los tipos estáticos. Incluso los lleva en el nombre. Para muchos el mero hecho de poder disponer de un sistema de tipos estáticos es suficiente, pero es que además el sistema de tipos del TypeScript actual tiene características que permiten una gran expresividad.
Tenemos, por supuesto, interfaces y clases para que resulte familiar a los usuarios de C# y Java (su público objetivo, no nos olvidemos). Esto estuvo desde siempre. A día de hoy también tenemos un tipado estructural bastante majo (no como C#, que tiene tipado estructural para cosas muy concretas, la posibilidad de utilizar tipos suma y tipos intersección o una curiosa forma de extender tipos.
Desgraciadamente la mayoría del código que he visto en internet se limita a traducir código con un estilo muy C# a TypeScript, por lo que no parece que se le esté sacando demasiado partido a estas características. Vamos, que en general cuesta ir más a allá del sistema de tipos de C# o Java.
El tooling alrededor de TypeScript está razonablemente bien conseguido. Todos los editores medianamente populares tienen plugins para trabajar con él que permiten hacer las cosas básicas: comprobar sintaxis y tipos en tiempo real (o casi real), mostrar documentación, autocompletado, renombrar símbolos, ir a la definición. Se agradece, sin duda. Aunque este tipo de herramientas nos pueda llevar a escribir auténticas aberraciones, también nos ayudan a ser más productivos.
Al final, todas estas características hacen que sea un lenguaje muy accesible, tanto para la gente que viene de Javascript como para la gente que viene de C#/Java. Eso es un punto a favor a la hora de considerar usarlo para proyectos de larga duración, porque debería facilitar futuras incorporaciones al equipo.
Lo no tan bueno
Ha habido cosas que no me han gustado mucho, que creo que son decisiones erróneas o que me han dado un poco de miedo.
Tú código no vive aislado del mundo y muchas de las librerías que vas a utilizar, o mejor dicho, que yo quiero utilizar, están escritas en Javascript. La interoperabilidad entre TypeScript y Javascript es magnífica, pero para poder explotar las partes buenas de TypeScript, necesitas tipos, y las librerías de Javascript que vas a utilizar no incluyen esas definiciones de tipos.
Esto se resuelve con unos preciosos ficheros, las definiciones de tipos, que podemos descargar de distintos repositorios y contienen anotaciones de tipos para las APIs de la mayoría de librerías de Javascript. Si no encontramos lo que necesitamos podemos crearnos nosotros mismos nuestra definición de tipos, pero lleva su tiempo.
Con esto de las definiciones de tipos he encontrado dos problemas.
Uno, que aquí el ecosistema de TypeScript se parece mucho al de Javascript y cambia cada poco tiempo. Ahora la herramienta recomendada para gestionar las definiciones de tipos es typings. Hasta hace poco, se usaba otra herramienta, tsd, que todavía se usa para algunas cosas. Pero no os preocupéis, que en TypeScript 2, que sale este año, todo esto vuelve a cambiar y las definiciones de tipos se distribuirán por npm. ¿A que es divertido?
Dejando eso de lado, que para eso he sobrevivido a Javascript unos cuantos años y estoy acostumbrado, otro problema con las definiciones de tipos es que complica gestionar las versiones de las dependencias que tienes.
En Javascript, si por ejemplo usabas React, React-Router y Material UI, y querías actualizar React, tenías que esperar a que React-Router y Material UI (ambas dependientes de React) se actualizasen primero. Ahora con TypeScript, si quieres usar las definiciones de tipos no sólo tienes que esperar a que se actualicen las librerías, sino también sus definiciones de tipos correspondientes.
De hecho, por lo que he visto hasta ahora las definiciones de tipos suelen ir al menos una versión por detrás de la librería correspondiente. No lo considero un factor crítico porque normalmente cuando desarrollo en Javascript las librerías se me quedan desactualizadas a los 20 minutos, pero si eres un obseso de estar a la última, tenlo en cuenta.
Otra cosa que creo que es un error es la inclusión de soporte para JSX en el propio compilador. Y mira que, como usuario de React, me viene muy bien; pero creo que el lenguaje debería estar por encima de librerías concretas, y si dentro de 4 años React y sus derivados ya no están de moda, no creo que el lenguaje deba cargar con el soporte para esa sintaxis.
Llegado ese caso, todas las opciones son malas: si mantienes el soporte a JSX estás asumiendo un coste de mantenimiento inútil, pero si lo quitas, haces que la gente que lo esté usando no pueda aprovechar características de versiones nuevas.
Lo razonable hubiese sido que el soporte para JSX fuese a través de un plugin o similar, posiblemente aprovechando el plugin de Babel, igual que se hace en Javascript, pero a Microsoft todavía le cuesta eso de no controlar todo.
Y esto nos lleva al tercer punto, el del miedo. Que TypeScript esté desarrollado por Microsoft me genera inseguridad. Hace unos años (no muchos) hubiera sido todo lo contrario y lo hubiera visto como una garantía de continuidad y calidad. En los últimos tiempos lo que me transmiten las deciciones de Microsoft es duda, y no sólo en la parte de desarrollo con cosas como .NET Core, sino también en otras áreas como sistemas operativos o movilidad.
Me da la sensación de que no tienen muy claro lo que quieren hacer y, mucho menos, cómo lo quieren hacer, por lo que temo los bandazos que pueda acabar dando TypeScript si, por ejemplo, deciden dentro de 1 año que va a ser parte crítica de .NET Core y empiezan a llenarlo de cosas raras para que funcione mejor sobre él porque piensan que eso les dará puntos dentro de la comunidad node.js o veté tú a saber qué.
Que Google haya decidido adoptarlo en Angular 2 ayuda un poco a recuperar la confianza. No es que Google sea un claro ejemplo de continuidad y cuidado por sus usuarios, recordad que Angular 2 empezó desarrollándose en Javascript, de ahí pasó a AtScript, y de ahí a TypeScript, pero al menos ya son dos empresas grandes que podrían acabar teniendo interés en que TypeScript siguiera funcionando dentro de unos parámetros razonables.
Otras alternativas
Durante nuestros experimentos con otros lenguajes han surgido varias alternativas que han llamado nuestra atención por un sentido u otro. Personalmente, había lenguajes que me parecían extremadamente más interesantes como (por supuesto) ClojureScript, PureScript o Elm, pero siendo realista, apostar por un lenguaje así supone estar dispuesto a asumir que futuras incorporaciones al equipo sean mucho más complicadas, tanto técnica como económicamente.
Una vez descartados los lenguajes interesantes, había dos opciones más viables.
Kotlin, que es un lenguaje desarrollado por JetBrains (los creadores de IntelliJ y ReSharper) bastante accesible pero con características modernas. Quizá con demasiadas características (a veces parece que están intentando meter soporte a todo lo que se les ocurre sea como seas), pero el factor determinante es que todavía el soporte para compilar a Javascript está en fase experimental.
Flow realmente no es un lenguaje, sino una extensión para Javascript que permite escribir anotaciones de tipos y validarlas de forma estática. Me gustaba la idea de mantener la sintaxis y semántica de Javascript sin casi ningún cambio, pero como pasa con tantos proyectos modernos, no tiene soporte para desarrollar en windows, y a día de hoy eso, por desgracia, sigue siendo fundamental para mi.
Conclusión
Empezaré por algo totalmente subjetivo y personal: TypeScript me parece un lenguaje aburrido. Puede que si llego a trabajar más con él y a exprimir su sistema de tipos me acabe divirtiendo (tengo ciertas esperanzas), pero a día de hoy, programar en TypeScript no me motiva mucho.
Es un lenguaje práctico, que no es poco, y con una curva de aprendizaje suave. En ese sentido, resulta adecuado para proyectos que vayan a perduran en el tiempo y puedan requerir variar la composición del equipo. Debería ser fácil encontrar gente que lo conozca o pueda aprenderlo sin muchos problemas.
¿Lo acabaré usando en producción? No lo sé. Es posible. También depende de cuándo decidiera usarlo. Kotlin y Flow, dos alternativas que no están maduras actualmente podrían servirme dentro de unos meses.
¿Recomendaría invertir tiempo en él? Depende. Aquí mi opinión no ha variado mucho con respecto al post de hace 3 años.
Si ya conoces C# o Java, aprender directamente Javascript te va a exponer a más conceptos nuevos y, además, lo vas a necesitar de todas formas si cuando trabajes con TypeScript. No lo veo como un lenguaje que merezca la pena aprender si no lo vas a usar en un proyecto real. Eso no quiere decir que sea un mal lenguaje, simplemente que me parece un lenguaje más práctico que interesante.
Posts relacionados: