Cuando empecé a programar para web me encontraba cómodo con PHP y Javascript, me permitían el salvaje mundo de no definir la estructura de los datos y de reutilizar variables. Mientras, estaba aprendiendo Java y «sufriendo» la definición de clases y tipos. Era joven e inexperto. No sabía que esto está muy bien cuando estás tirando código rápido tú solo. Está bien para prototipar, hacer una prueba de concepto con pocos ficheros y pocas funciones, cuando tienes todo el código en tu cabeza. Ideal para un hackaton o similar.
Pero cuando llegas al mundo real, empiezas a utilizar librerías, a compartir código con otras personas, a tener que entender como funciona código ajeno (a veces sin leer documentación, por que no la hay). Si, ahora prefiero un código que se expresa por si solo, más allá de buenos nombres de variables o funciones, está un buen tipado, entender que puedo esperar de una función y como espera esa función ser usada, construir objetos que tienen sentido.
TypeScript evoluciona JavaScript, de hecho es más «java» ya que no solo tiene orientación a objetos sino que me devuelve a ese fuerte tipado. Sin embargo, los navegadores ejecutan javascript, así que el código TypeScript que hagamos tendrá que llevar una fase de compilación para convertirse en JS. Lo bueno, que en esa compilación saltarán errores de tipado que nos ayudarán a tener un JS más limpio y estable, pillando errores como asignaciones inválidas antes de runtime, lo que reduce bugs en producción hasta un 15-20%.
La curva de aprendizaje es mayor que JS, y quizá podemos entrar haciendo JS (para conocer como funciona y sabiendo que podríamos estar haciendo chapuzas) y luego dar el salto a TS para aprender de interfaces y tipos. Las interfaces definen contratos para objetos/APIs, facilitando el uso de funciones ajenas como cajas negras (sabemos lo que tenemos que darle y tenemos garantizado lo que sale, nos da igual lo que pasa dentro).
La principal desventaja es que hay que preparar un entorno de compilación y eso puede resultar engorroso poner en marcha. Además esa compilación lleva a retrasar unos segundos cada cambio que hagamos en nuestro desarrollo para poder probarlo. Pero si vamos a trabajar con frameworks modernos, con proyectos medianos-grande… no lo dudaría ni un segundo.
Por otro lado, que placer es el autocompletado que te aporta en el IDE poder tener clara la librería que estás usando.
Proyectos legacy: de JS a TS
[Leer más en TypeScript: Migrating from JavaScript]
Lo ideal en un proyecto legacy es ir cambiando piezas poco a poco, no queremos tirarlo todo y empezar de cero. La compilación de TypeScript permite usar código JS puro, pero aquí entraremos en terreno pantanoso que tendremos que andar con cuidado.
Lo ideal en este caso será reemplazar de fuera hacia dentro, ya que el core suele estar fuertemente acoplado. Iremos migrando piezas por su valor en negocio (criticidad, mantenimiento…) a fondo e ir cambiando su nivel de «strictness» de manera local. Creamos types para lo que necesiten estos módulos (que ya se usarán en toda la aplicación) y separamos responsabilidades.
Lamentablemente (o como solución temporal), usaremos el type any con toda relación con el núcleo que no ha sido migrado (dejando anotada esta deuda), pero solo en esas conexiones.
Cuando estén migrados todas las capas exteriores podremos ponernos serios con el core de la aplicación y levantar el nivel de strict de manera global.