TypeScript: una nueva forma de codificar JavaScript

Una de las últimas novedades anunciadas para el desarrollo de aplicaciones con JavaScript es TypeScript , una mejora sobre JavaScript que permite codificar este lenguaje de una manera novedosa en la que ha estado trabajando Anders Hejlsberg. Su principal característica es que opcionalmente podemos utilizar tipado estático para estructurar mejor nuestro código. Gracias a esta técnica de tipado estático sobre JavaScript conseguiremos un desarrollo escalable y mucho más mantenible que con código JavaScript normal, sin perder el carácter dinámico de este lenguaje.

Lo que es y lo que no es TypeScript

TypeScript NO se trata de un nuevo lenguaje de programación, simplemente es un superset de JavaScript que nos permite, principalmente, utilizar técnicas como el tipado estático de las variables y la encapsulación (mediante una estructura de clases y módulos) para generar un código más fácil de mantener, más legible y en el que se reducen los errores más comunes de forma notable. Que se nos permita utilizar este tipado estático no quiere decir que sea obligatorio, ya que podremos utilizarlo sólo cuando consideremos necesario para estructurar mejor nuestro código, y en ningún momento este tipado afectará al carácter dinámico de JavaScript. De hecho, cualquier código JavaScript funcionará perfectamente en nuestros ficheros escritos en TypeScript sin que se realice ninguna transformación del mismo, y todas las librerías de JavaScript (DOM, jQuery, node.js…) funcionan en nuestros ficheros en TypeScript . De hecho, las librerías se incluyen con la extensión .ts en la que, simplemente, se realiza el tipado estático de todas las variables y funciones utilizadas. Como ya hemos dicho, al poder utilizar directamente código JavaScript todos los tipos estáticos y las definiciones de clases son opcionales, y podemos utilizarlos simplemente cuando creamos necesario. 

El código escrito con TypeScript se compila a JavaScript “plano” de manera automática. Todo esto nos permite realizar un código en el que encontraremos menos errores no controlados y que será más fácil de depurar, ya que establecemos de antemano qué tipo de variable estamos usando en cada momento.

La gran ventaja de este superset es que comienza y termina con JavaScript: el código JavaScript funciona correctamente (simplemente copia y pega algo de código JavaScript para comprobarlo) y el código TypeScript se compila a JavaScript, por lo que funcionará perfectamente en cualquier navegador, en cualquier host y en cualquier sistema operativo.

Sistema de tipado

Con TypeScript se realiza una formalización de los tipos de JavaScript, mediante una representación estática del sistema de tipos dinámico que utiliza JavaScript. Aunque, en la práctica, pocas anotaciones acerca del tipo son necesarias, algunas son fundamentales y nos ahorran horas en el momento de corregir o extender/modificar un código creado previamente (mejora de la mantenibilidad). Además, gracias a este sistema de tipos, los archivos de declaración pueden escribirse y mantenerse de forma separada a los archivos de código, al igual que se hace con las librerías.

El sistema de clases y módulos nos permite realizar aplicaciones con estructura escalable, ya que clases, módulos e interfaces establecen una relación muy clara entre componentes y se consigue una estructura muy similar al modelo de la programación orientada a objetos. Cabe destacar que toda esta sintaxis de clases y módulos es una implementación de la sintaxis propuesta por el estándar ECMAScript Harmony (ES6) , con todos los beneficios futuros que se deducirán cuando este estándar esté disponible para todo el mundo, y también soporta los módulos de CommonJS y AMD en cualquier entorno compatible con ECMAScript 3.

Demo

Veamos cómo funciona todo esto con un ejemplo muy simple. Partimos de una clase Poligono de la que heredarán las clases Rectangulo y Triangulo. Vamos a ver la comparación entre el código escrito en TypeScript y la compilación que realiza a JavaScript:

TypeScript

class Poligono {

constructor(public name: string) { }

perimetro(cm: number) {

alert("Perímetro de " + this.name + ": " + cm + " cm.");

}

}

class Rectangulo extends Poligono {

constructor(name, public a: number, public b: number)

{

super(name);

}

perimetro() {

var n = this.a + this.a + this.b + this.b;

super.perimetro(n);

}

}

class Triangulo extends Poligono {

l: number;

constructor(name, l: number)

{

super(name);

this.l = l;

}

perimetro() {

var n = this.l + this.l + this.l;

super.perimetro(n);

}

}

var r = new Rectangulo("Rectángulo", 5, 2)

var t = new Triangulo("Triángulo", 3)

r.perimetro();

t.perimetro();

JavaScript

var __extends = this.__extends || function (d, b) {

function __() { this.constructor = d; }

__.prototype = b.prototype;

d.prototype = new __();

}

var Poligono = (function () {

function Poligono(name) {

this.name = name;

}

Poligono.prototype.perimetro = function (cm) {

alert("Perímetro de " + this.name + ": " + cm + " cm.");

};

return Poligono;

})();

var Rectangulo = (function (_super) {

__extends(Rectangulo, _super);

function Rectangulo(name, a, b) {

_super.call(this, name);

this.a = a;

this.b = b;

}

Rectangulo.prototype.perimetro = function () {

var n = this.a + this.a + this.b + this.b;

_super.prototype.perimetro.call(this, n);

};

return Rectangulo;

})(Poligono);

var Triangulo = (function (_super) {

__extends(Triangulo, _super);

function Triangulo(name, l) {

_super.call(this, name);

this.l = l;

}

Triangulo.prototype.perimetro = function () {

var n = this.l + this.l + this.l;

_super.prototype.perimetro.call(this, n);

};

return Triangulo;

})(Poligono);

var r = new Rectangulo("Rectángulo", 5, 2);

var t = new Triangulo("Triángulo", 3);

r.perimetro();

t.perimetro();

Como podemos ver, el único código que se introduce sin que nosotros lo hayamos escrito en TypeScript es la declaración del extends, necesario para que las clases hijas hereden de Poligono.

El tipado estático se realiza mediante la anotación del tipo detrás del nombre de la variable ([clase Rectangulo] a: number). Como ya hemos dicho, establecer el tipo de las variables es opcional, pero haciéndolo permitimos al compilador comprobar que los parámetros introducidos son del tipo correcto durante la compilación, reduciendo el número de errores en tiempo de ejecución y haciendo nuestro código mucho más sencillo de depurar.

En cuanto a la definición de las clases, podemos ver dos formas de hacerlo: definir en el constructor los miembros que tendrá, con sus tipos ([clase Rectangulo] constructor(name, public a: number, public b: number)) o definir el miembro fuera del constructor ([clase Triangulo] l: number) y definir su valor dentro del constructor ([clase Triangulo] constructor(name, l: number) { super(name); this.l = l;} ). En cualquier caso, el código generado en JavaScript es exactamente el mismo.

Para probar este pequeño sample recomendamos utilizar el Playground, introduciendo el código TypeScript en la columna izquierda, comprobando el código JavaScript generado y el resultado obtenido al ejecutarlo (pulsando Run). También os animamos a que hagáis vuestras pequeñas pruebas utilizando esta herramienta, ya sea con este ejemplo, con las plantillas que vienen definidas o con cualquier código propio que queráis probar.

Para probarlo con Visual Studio 2012, primero hay que instalar el plugin que nos permite utilizar TypeScript. Una vez hecho esto seleccionamos Nuevo Proyecto > Aplicación web de ASP.NET MVC 3

Screenshot (5)

Y luego seleccionamos “TypeScript Internet Application”:

Screenshot (6)

Una vez dentro del proyecto, en la carpeta “Scripts” podemos encontrar el fichero “site.ts” al que llama por defecto la aplicación, donde sustituiremos el código que viene por el que queremos probar.

Screenshot (7)

La compilación a JavaScript no se realiza de forma automática al guardar el fichero .ts, debemos compilar nosotros la solución para ver el código JavaScript que se genera en “site.js”, fichero que aparece “colgando” de nuestro fichero .ts

Screenshot (8)

Por último, implementamos nuestra aplicación web en Internet Explorer para comprobar que todo funciona correctamente:

Screenshot (9)

Screenshot (10)

También podemos, simplemente, crear un nuevo archivo TypeScript, escribir nuestro código y compilarlo utilizando la consola del Administrador de paquetes (Ver > Otras ventanas > Consola del administrador de paquetes) con el siguiente comando:

tsc <ruta del archivo>/<nombre del archivo>.ts

Screenshot (11)

Con lo que generaremos un archivo .js con nuestro código TypeScript compilado a JavaScript en la misma ruta y con el mismo nombre (sólo cambia la extensión de .ts a .js)

 

Por último, si preferimos usar otro tipo de proyecto como ASP.NET Web Forms o MVC 4, tendremos que añadir de forma manual el siguiente código en el archivo .csproj para que los ficheros .ts sean compilados junto con el proyecto:

<``TargetName``=``"BeforeBuild"`` >

<``ExecCommand="&amp;quot;$(PROGRAMFILES)\Microsoft SDKs\TypeScript.8.0.0\tsc&amp;quot; @(TypeScriptCompile ->'&quot;%(fullpath)&quot;', ' ')" />

</``Target``>

Esta porción de código debemos añadirla al final del archivo .csproj del proyecto, sustituyendo (o complementando, si ya tenemos eventos de compilación) la sección <Target> del mismo.

 

Descarga

Si no puedes esperar a probarlo por ti mismo, puedes descargar una preview de TypeScript dirigiéndote a https://www.typescriptlang.org/, donde podrás obtener:

  • Compilador: open source y escrito en TypeScript
  • Herramientas: plugin para Visual Studio y el Playground del navegador para realizar pequeñas pruebas
  • Librerías: librerías de JavaScript completamente tipadas de forma estática
  • Ejemplos y especificación del formato de TypeScript

 

Resumiendo

  1. TypeScript NO se trata de un lenguaje nuevo, sino de una extensión de JavaScript que nos permite utilizar tipado estático y una estructura basada en clases y módulos siguiendo el modelo de la programación orientada a objetos.
  2. El sistema de tipado estático NO es obligatorio, es una opción que nos permite TypeScript.
  3. La sintaxis de clases y módulos es una implementación de la sintaxis propuesta por el estándar ECMAScript Harmony (ES6).
  4. Todo código JavaScript es, directamente, código TypeScript.
  5. Puedes comenzar a probarlo utilizando diferentes herramientas como el Playground de la web de TypeScript o Visual Studio 2012.

 

 

Un saludo,

Gorka Madariaga (@Gk_8)