Introducción a TypeScript

Problemas con JavaScript

Cualquier desarrollador que ha trabajado con JavaScript nativo ha sufrido en sus propias carnes los números problemas que se generan principalmente cuando aparece un error, lo difícil que es detectar dicho error principalmente cuando el código se va incrementado.

Estos problemas, se produce debido a que en sus inicios JS fue desarrollado con el propósito de crear pequeños scripts simples.

No muestra los errores durante el desarrollo

Una de las características de JavaScript es que es interpretado, y esta interpretación de su código se realiza cuando realizamos el llamado del archivo JS. Por ello, y como ya vimos en el artículo de ¿Por qué JS es de tipado débil y dinámico? Al tratarse de un lenguaje interpretado en tiempo de ejecución y no previamente (compilado), nos encontraremos los errores en nuestro código en tiempo de ejecución y no durante el desarrollo. Esto, además, esta característica le permite a JavaScript ser un lenguaje de tipado débil y dinámico. El precio de no ser compilado es, por tanto, que no le permite mostrar errores en el código durante la fase de desarrollo.

Por ello, el mecanismo para encontrar/solucionar estos errores es en tiempo de ejecución y, por lo tanto, nos obliga a ir al navegador y ver en qué línea nos falla. No lo podemos ver en el propio IDE directamente como en otros lenguajes de programación, (si fuera compilado lo podríamos ver en tiempo de compilación) sino que lo hacemos desde el navegador. Un ejemplo de ello puede ser:

Si miramos nuestro código de main.js no podemos apreciar ningún error.

Pero cuando ejecutamos nuestro index.html que carga el script de JavaScript main.js podemos ver que nos aparece un error de que total no está definido.

El ser un lenguaje interpretado (que se interpreta en tiempo de ejecución) ralentiza algo más el tiempo de desarrollo ya que no podemos ayudarnos del IDE. Y el navegador tampoco nos ayuda en exceso, nos hace ir constantemente a la consola del navegador. 

Problemas del tipado débil y dinámico

Otro de los problemas que más quebraderos de cabeza otorgan a los programadores son los errores provocados por el tipado débil y dinámico de JS. Esto significa que sobre una variable no tenemos que definir el tipo de dato con el que vamos a trabajar (tipado débil) y que además podemos modificar a otro el tipo de dato almacenado en una variable en cualquier momento (tipado dinámico).

Ya que si, por ejemplo, dentro de una función esperamos un número en un parámetro y no controlamos que sea un número. Al no asegurarnos que es de un tipo significa que se puede recibir un string, un numero u otro tipo de dato, hasta un objeto, esto puede suponer tener serios problemas en nuestro código.

Un ejemplo de ello, podría ser:

Si nos fijamos, en este caso nos suma los números , el resultado esperado y para el que hemos desarrollado la función. Pero, además, nos suma un true con un 5, nos concatena 22 con 55, nos junta texto. Por decirlo así, se lo come todo (peras, manzanas, etc.) y esto puede dar muchos problemas.

Si manejamos los errores como en el siguiente ejemplo:

Que podamos controlar los tipos de dato no significa que este tipo de característica de JS no facilite que se produzcan errores que no esperamos en tiempo de ejecución.

Podemos manejar los casos en los que no se introducen dos tipos numéricos evitando que se realicen sumas, mostrando errores, etc.

Compatibilidad de navegadores con distintas versiones de EcmaScript

Hasta el momento no hemos hablado tampoco de la compatibilidad de las diferentes versiones de JavaScript con los navegadores ¿Si usamos la versión más reciente de EcmaScript, creéis que está será compatible con todos los navegadores? La respuesta ya os digo que es un NO como una casa.

Si nos metemos en una tabla de compatibilidad de versiones de EcmaScript como la que he encontrado muy chula (es un repositorio de Git Hub sobre podéis hacer hasta un Fork [Fork = copia] en vuestra cuenta si es que tenéis una).

Si os metéis en ella, podéis ver la compatibilidad de cada función en cada uno de los navegadores:

Por ejemplo, ¿Este código se ejecutará en Internet Explorer 11? La respuesta vuelve a ser un NO como una casa.

Vemos que tiene una Arrow function (se introdujeron en EcmaScript 6). Si nos metemos en ese apartado y buscamos su compatibilidad, podemos ver que no son compatibles.

¿Os imagináis constantemente mirando constantemente que versiones son compatibles con las funcionalidades que utilizáis para desarrollar vuestro website? No sé vosotros, pero yo no.

Todas estas necesidades entre otras, han provocado que realizar una aplicación con JavaScript nativo (vanilla) a gran escala provoque una sensación de falta de robustez. ¿Cuál es la solución a todos los males de JavaScript? TypeScript.

Historia de TypeScript

En 2012 Microsoft, percatándose de algunos problemas como los que acabamos de ver en JavaScript nativo (vanilla) e intentando solventarlos en las aplicaciones de gran escala o que en un futuro puedan requerir escalar (crecer) crea el proyecto Strada.

Dentro del proyecto Strada, trabaja Anders Hejlsberg (podríamos “bautizarlo como el padre” de TypeScript además de muchos otros lenguajes de programación como Pascal, Delphi y C#) acompañado de su equipo formado por 50 desarrolladores más.

Tras dos años trabajando en la construcción de TypeScript, y tras acabar el desarrollo Microsoft (la empresa propietaria de Typescript) lo lanza al mercado.

Typescript, por tanto, busca crear aplicaciones robustas, con las herramientas más avanzadas de desarrollo de aplicaciones.

¿Qué es TypeScript?

TypeScript = Un superSet o superConjunto

Y ¿Qué es un SUPERSET o superconjunto?

Un superconjunto es un conjunto que incluye todos los elementos (y posiblemente más) de otro conjunto.

En este caso, TypeScript es un superset (un lenguaje de programación), escrito sobre otro lenguaje de programación como es JavaScript.

Aterrizando en JavaScript

Vamos a aterrizar en TypeScript realizando una vista de pájaro de que novedades tiene respecto a JS.

Si vamos a la web de typescriptlang.org, podemos trabajar con TypeScript sin realizar instalación alguna. Vamos a ver un ejemplo:

Nosotros hemos escrito el código de la izquierda que representa que está “en TypeScript” y el de la derecha es JavaScript. Si miramos el código de un lado y del otro, podemos ver que es idéntico, y que nada ha cambiado.

TypeScript, no es compatible con los navegadores, pero JavaScript sí. Por ello, el código que escribimos en TypeScript (TS) tiene que realizar un proceso de compilación (el nombre en concreto es transpilar, en este caso, por tanto, realiza una transpilación)

De hecho, si ejecutamos el código pulsando Run, podemos ver que el resultado es el mismo que el de antes:

Pero si vamos a TS Config podemos modificar la configuración de a que versión de JavaScript traduciremos nuestro código de TypeScript. Para ello, debemos modificar el target. Actualmente, en mi caso, está en la versión: ES2017

Si lo modifico a ES5, le estamos diciendo que nuestro código de TypeScript se va a traducir a EcmaScript 5. Lo que significa que cuando nuestro código de TypeScript realice la transpilación (compilación) a JavaScript para que pueda ser ejecutado en los navegadores, será compatible con todos los navegadores de la actualidad sin problema.

Si observamos el código, podemos apreciar que ahora sí que tenemos diferencias entre nuestro TypeScript y el JavaScript. Y que se ha cargado la estructura de arrow function y la ha substituido por una function tradicional.

Esto, es debido a que hemos configurado la transpilación (compilación) de nuestro TypeScript hacía la versión 5 de EcmaScript y como ya hemos visto en un apartado de este artículo anteriormente las arrow functions son una novedad que se introduzco a partir de la versión EcmaScript 6 y no son compatibles con Internet Explorer 11.

VENTAJA 1: TypeScript nos permite traducir código moderno (de una versión de EcmaScript actual) a cualquier versión anterior de JavaScript. Proporcionándonos una mayor compatibilidad con versiones más antiguas de los navegadores.

Por lo que si queremos tener compatibilidad con IE11 con esta configuración podremos utilizar arrow functions desde TypeSript sin problemas ya que en el proceso de transpilación recibiremos un código JavaScript que podrá ejecutar el navegador sin problemas.

Si nos fijamos, en nuestro código, podemos ver que en TypeScript sí que se nos muestran los errores en tiempo de ejecución. Y que tenemos num1 y num2 resaltados. Es más, en la pestaña Errors, nos aparece una advertención en roja con un número 2. Si nos metemos dentro de Errors, vemos que se ponen en rojo los parámetros de nuestra función, arrojándonos un error de que los parámetros dentro de la función que reciben any (cualquier tipo de dato).

Esta mejora de TypeScript, se produce debido a que TypeScript añade tipos estáticos, por lo que se debe realizar transpilación y ya se pueden detectar los errores desde el IDE, además se puede especificar el tipo de dato que recibiremos en un parámetro o variable (tipos estático) pero no es obligatorio ya que como TypeScript es un superSet, trabaja por debajo con JavaScript y por ello, nos permite ejecutar el código, aunque nos recomienda especificar un tipo de dato para nuestros parámetros. Pero pese a ello, si lo ejecutamos, ya hemos visto que nos muestra el resultado.

VENTAJA 2: TypeScript nos muestra los errores en tiempo real desde entorno (No nos hace falta ir al navegador)

Algunas de las soluciones podrían ser:

  • Contemplar que en nuestra función suma puede entrar cualquier tipo de parámetro, y por tanto le especificaremos que any acompañado de dos puntos justo después del nombre de cada uno de los parámetros:

  • Si le especificamos que los parámetros de la arrow function son de tipo number, podemos ver que nos muestra un error sobre todo los tipos de datos que no sean type number.

Si lo modificamos, podemos ver que se solucionan los errores y que funciona correctamente:

VENTAJA 3: TypeScript nos permite definir el tipo de dato con tipado estático, aunque no es obligatorio sí que es muy muy muy recomendable.

Instalando TypeScript

Hasta ahora hemos trabajado con TypeScript desde aquella web. Pero el objetivo de usar typeScript es utilizarlo en nuestras webs tanto utilizar TypeScript sobre nuestras webs en HTML, CSS & JS, como con Angular, React, Vue, etc. O incluso ejecutarlo desde Node.js.

Para instalar TypeScript primeramente tenemos que tener instalado:

  • VSC: el que es sin duda alguna ahora mismo el IDE, el entorno de trabajo más potente para el desarrollo web.
  • Node.js: lo usaremos para ejecutar nuestro código. Además, también usaremos su gestor de packages (Node Package Manager) para instalar TypeScript. Por ello, descargaremos la versión LTS (Long Time Support) desde la web oficial de node y lo instalaremos como siempre pulsando siguiente, siguiente…

Una vez instalados ambos, abrimos el VSC y vamos a Terminal > New Terminal:

verificamos la instalación de node y de npm desde VSC con el comando -v el cual nos mostrará su versión tanto de node como de npm:

Perfecto, una vez instalado node y npm, vamos a realizar la instalación de forma global de typescript. Además, revisaremos la versión con tsc -v

Realizando nuestra primera transpilación (compilación) con TS desde Terminal:

Bien, una vez instalado, vamos a realizar la primera transpilación desde nuestro terminal.

Para ello, creamos un proyecto desde VSC y añadimos un fichero index.html y otro llamado main.ts (con extensión de TypeScripts .ts):

Si realizamos la transpilación, podemos ver que se nos generará el archivo de JavaScript con extesión .js:

Si nos metemos en main.js podemos ver que nos lo ha creado correctamente (en EcmaScript 5). Pero que cuando nos ponemos encima de saludar de main.ts nos aparece un error:

Solucionando el error: “Cannot redeclare block-scoped variable ‘saludar’.ts(2451)” ¿Qué está pasando?

Cuando se produce un error como este es debido a que existe una confusión semántica que tenemos que desambiguar (resolver) ya que no sabe si tratarlo como un módulo (que tendrá su propio alcance) o como un script (que compartirá su alcance global con el resto de scripts).

Ante la duda, trata al archivo de TypeScript como un script y por tanto comparte su alcance global con el resto de scripts entre los que se incluye main.js. Por ello, la constante saludar que contiene una arrow function y la var saludar que contiene una función entran en conflicto.

De hecho, si eliminamos el archivo main.js, podemos ver que el problema se soluciona:

Pero a la que rehacemos el main.js, volvemos a tener el problema:

Podemos ver que:

  1. La palabra clave const o let tiene un alcance de bloque y, a diferencia de  var, no se puede volver a declarar ni reasignar dentro del mismo bloque.
  2. Después de la Transpilación, la variable que contiene nuestra arrow function saludar dentro de nuestro archivo main.ts ahora también está disponible en el archivo main.js Transpilado como “var saludar()” .
  3. Ahora mismo, después de la transpilación, hay esencialmente dos variables con el mismo nombre saludar(); una situada en nuestro main.ts que se declara como const o let  (recuerda que let no se puede volver a declarar ni reasignar) y otra en main.js
  4. Entonces, naturalmente, el código de Visual Studio muestra el error en el archivo main.ts porque la variable allí se declara con la palabra clave const o let.
  5. Como resultado, no permitirá transpilar el archivo y muestra No se puede volver a declarar la variable de ámbito de bloque “saludar”.

TypeScript es modulador y eso significa que cada módulo tiene su propio bloque.

Entonces, básicamente, vamos a buscar la manera más sencilla de encerrar la variable que se declara como let/const dentro de su propio módulo, el error se resolverá porque ahora su variable let/const está en su bloque separado.

Por ello, y para que TypeScript reconozca nuestro main.ts como un módulo que tiene su propio alcance, y poder solucionar el problema, simplemente tendremos que realizar un export {} (que puede estar vacío sin problema alguno) o un import en la parte superior del archivo.o.

Ahora podremos ver que el error está resuelto.

Ejecutando nuestro archivo JS

Ahora finalmente, solo nos queda ejecutarlo.

Desde node.js:

Si lo hacemos desde node:

Si vamos a transpilar y a ejecutar desde node podemos utilizar la siguiente instrucción con lo que concatenaremos ambas instrucciones:

Desde HTML:

Y si lo hacemos desde nuestro HTML:

Si, por ejemplo, cambiamos el parámetro de la función saludar e intentamos compilar, podemos ver que nos arrojará un error.

Pero ya sabemos cómo solucionarlo, así que no hay problema:

Espero que os haya gustado. Y muchas gracias por leer el artículo, hasta la próxima. ¡Saludos!

4 comentarios

  1. Thanks in support of sharing such a nice thinking, post is fastidious, thats
    why i have read it entirely

  2. Piece of writing writing is also a excitement, if you be acquainted with afterward
    you can write if not it is difficult to write.

  3. My brother suggested I might like this website. He was totally right.
    This post actually made my day. You cann’t imagine simply how much time I had spent for this information! Thanks!

    asmr https://app.gumroad.com/asmr2021/p/best-asmr-online asmr

  4. Thanks , I’ve recently been looking for info about this subject for a while and yours is the greatest I have discovered so far.

    However, what concerning the conclusion? Are you certain in regards to the supply?
    ps4 games https://j.mp/3nkdKIi ps4 games

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

La Ley 34/2002 nos obliga a avisarte de que usamos cookies propias y de terceros con objetivos estadísticos y de sesión y para mostrarte la 'publi' que nos da de comer. Tranquilo, este mensaje solo sale una vez. Más información

Java desde 0 comunica a los usuarios, a través de este aviso, que puede utilizar cookies cuando el usuario navega por las diferentes pantallas y páginas del sitio. Durante el uso de nuestra página Web usted acepta y autoriza expresamente el uso de cookies, de acuerdo con nuestra Política de Privacidad. Este sitio web utiliza las siguientes cookies propias: - Cookies de sesión, para garantizar que los usuarios que escriban comentarios en el blog sean humanos y no aplicaciones automatizadas. De esta forma se combate el spam. Este sitio web utiliza las siguientes cookies de terceros: - Google AdManager y AdSense: Utiliza cookies para mejorar la publicidad. Entre otros fines, suelen utilizarse para segmentarla según el contenido que sea relevante para los usuarios o su ubicación, mejorar los informes de rendimiento de las campañas y evitar mostrar anuncios que los usuarios ya hayan visto. Las cookies no contienen información personal identificable. Consulta cómo utiliza Google la información de sitios web o aplicaciones. y cómo bloquear determinados anuncios. - Google Analytics: Almacena cookies para poder elaborar estadísticas sobre el tráfico y volumen de visitas de esta web. Al utilizar este sitio web está consintiendo el tratamiento de información acerca de usted por Google. Por tanto, el ejercicio de cualquier derecho en este sentido deberá hacerlo comunicando directamente con Google. - Redes sociales: Cada red social utiliza sus propias cookies para que usted pueda pinchar en botones del tipo Me gusta o Compartir.

Cerrar