AboutOpinionesBlogLa Blockletter

Software Crafters® 2025 | Creado con 🖤 para elevar el nivel de la conversación sobre programación en español | Legal

Home » typescript » Tutorial de Typescript, el javascript que escala. Introducción.
Tutorial de Typescript, el javascript que escala. Introducción.

Tutorial de Typescript, el javascript que escala. Introducción.

TypeScript es un superconjunto de Javascript, es decir, amplía Javascript con una nueva sintaxis que permite llevar JavaScript a otro nivel.

Miguel A. Gómez
Miguel A. Gómez · Seguir11 min read ·

Al suscribirte a la newsletter comparto contigo los 10 libros más importantes de programación. Los que sin duda todo dev debería leer al menos una vez...

Este es el primer artículo de una serie sobre el lenguaje de programación Typescript en la que abordaremos los fundamentos de este magnifico lenguaje open source. Typescript fue desarrollado en 2012 por Anders Hejlsberg, creador de Pascal, Delphi y C#, y su equipo en Microsoft.

Qué es Typescript

Esencialmente se trata de un superconjunto de Javascript, es decir, amplía Javascript con una nueva sintaxis que añade, entre otras cosas, el tipado estático opcional, genéricos, decoradores y elementos de POO como interfaces o property accessors.

TypeScript compila código JavaScript que se ejecuta en cualquier navegador, host, sistema operativo o motor de JavaScript que admita ECMAScript 3 (o más reciente).

typescript superset

Por qué Typescript

A lo largo de los últimos años Javascript ha crecido mucho y se ha convertido en el camino a seguir para escribir aplicaciones multiplataforma (aunque no el único, sigo siendo fan de Xamarin y C#). Las aplicaciones Javascript pueden ejecutarse en todas las plataformas, ya sea en móviles, web o escritorio. Sin embargo, cuando Javascript fue creado por primera vez su proposito no fue este, sino que fue diseñado para un uso simple en aplicaciones muy pequeñas.

TypeScript trata de resolver la mayoría de los problemas con JavaScript centrándose en mejorar la experiencia y la productividad de nosotros, los desarrolladores. Nos permite utilizar técnicas como el tipado estático opcional y/o la encapsulación para generar un código mucho más mantenible y escalable que con JavaScript tradicional, sin perder el carácter dinámico del mismo.

demás estos dos últimos años la popularidad de TypeScript se ha disparado y se perfila como uno de los lenguajes de programación con más futuro.

typescript-trend

Instalación de Typescript

Para poder instalar typescript el único requisito necesario es tener instalado en nuestro equipo nodejs y su administrador de paquetes (npm).

Cuando nos referimos a la "instalación de typescript" en realidad hacemos referencia a la instalación de su compilador, llamado tsc. Este se encarga de convertir el código TypeScript a Javascript con la versión ECMAScript compatible que deseemos.

Para instalarlo tan solo tenemos que ejecutar en la terminal lo siguiente:

npm install -g typescript

Para comprobar que la instalación se ha realizado correctamente ejecuta:

tsc -v

Esto nos mostrará la versión, en mi caso la 2.6

Uso de Typescript CLI

Para probar la instalación, creemos un archivo TypeScript simple llamado helloworld.ts con el siguiente código:

console.log("Hello world!")

El siguiente comando compilará un archivo

.ts
a un archivo
.js
:

tsc helloworld.ts

Esto creará un fichero

helloworld.js
. Este fichero lo podemos ejecutar en el navegador o como haremos en este caso, con Node:

node helloworld.js
//"Hello world"

El comando tsc se puede utilizar de formas muy variadas, veamos unos cuantos usos interesantes:

Compilar varios archivos

Para compilar varios archivos:

tsc hello1.ts hello2.ts hello3.ts

También podríamos utilizar asteriscos:

tsc *.ts

Esto compilará todos los ficheros typescript que se encuentren en el directorio. Cada fichero typescript se compilará en su archivo javascript correspondiente.

Unir archivos

También podemos compilar todos los archivos TypeScript en un solo archivo JavaScript. Esto nos ayudaría a reducir el número de solicitudes HTTP que un navegador debe realizar y de esta manera mejorar el rendimiento de nuestro sitio web. Para ello utilizaremos la opción --out del compilador:

tsc *.ts --out helloworld.js

Watcher

Si queremos evitar tener que compilar el archivo typescript cada vez que hagamos una modificación del mismo, podemos utilizar la opción

--watch
:

tsc *.ts --out helloworld.js --watch

Con esto conseguiremos que cada vez que guardemos las modificaciones el fichero se compilará automáticamente.

Creando un proyecto Typescript

Para crear un proyecto de TypeScript, lo único que necesitamos es crear un directorio y dentro del mismo crear un archivo de configuración de Typescript tsconfig.json. Este fichero, entre otras cosas, indica al compilador qué archivos compilar, qué archivos ignorar y qué a que version de javascript transpilar (por ejemplo, ECMAScript 3).

Para crear nuestro primer proyecto de TypeScript, creemos el nuevo directorio y agreguemos el archivo de configuración de TypeScript:

mkdir myProject
cd myProject
touch tsconfig.json

Configuración de Typescript

En este articulo ejecutaré todos los ejemplos en la terminal usando Node.js. Node corre sobre Chrome V8, uno de los motores de JavaScript más actualizados disponibles. La versión 6 de Node.js se envía con una versión de Chrome V8 capaz de soportar el 95% de la especificación ECMAScript 2015, como se muestra en Node Green, mientras que la versión 8 es compatible con el 99%.

Con respecto a ECMAScript 2017, ambas versiones admiten el 23% y el 73% de las especificaciones, respectivamente. Por lo tanto, la mejor opción es configurar nuestro proyecto para que se compile en ECMAScript 2015, lo que permitirá a los usuarios con Node.js 6 y 8 ejecutar los ejemplos sin problemas.

Además de indicar la versión de javascript, también configuraremos estas otras opciones del compilador:

  • module
    , indica a Typescript que use el formato CommonJS para los modulos.
  • removeComments
    , elimina los comentarios del código generado.
  • sourceMap
    , permite usar mapas de origen para asignar el código transpilado al código fuente.
  • outDir
    , indica el directorio en el cual se almacenará el código generado (build).
  • include
    , indica el directorio de los ficheros a compilar (src).

Nuestro fichero de configuración quedaría tal que así:

`{

"compilerOptions": { "module": "commonjs", "target": "es2015", "removeComments": true, "outDir": "./build" }, "include": ["src/**/*"] }`

Las opciones utilizadas en el archivo de configuración anterior son solo un pequeño subconjunto de lo que TypeScript admite. Por ejemplo, podríamos indicar al compilador que soporte decoradores, archivos tsx, etc. En la documentación oficial tenemos una lista con todas las opciones que admite el compilador.

Ahora que entendemos cómo iniciar un proyecto y cómo configurar el compilador, estamos listos para ir profundizando en las diferentes características del lenguaje.

Sistema de tipos

Sin lugar a dudas la principal característica de Typescript es su sistema de tipos, el cual realiza una formalización de los tipos de Javascript, mediante una representación estática de su sistema de tipado dinámico. Esto permite a los desarrolladores definir variables y funciones fuertemente tipadas sin perder la esencia de Javascript (su naturaleza debilmente tipada y su extremada flexibilidad). Poder definir los tipos durante el tiempo de diseño nos ayuda a evitar errores en tiempo de ejecución, como podría ser pasar el tipo de variable incorrecto a una función.

Veamos con un ejemplo de las ventajas que nos ofrece:

let myName: string = "Miguel"; let printName = (name: string) ={     console.log(name); }

Si intentamos ejecutar la función

printName()
pasándole un parámetro vacío o del tipo incorrecto el compilador nos advierte en tiempo de desarrollo, en lugar de generar excepciones en tiempo de ejecución. Además, el intellisense nos ayuda con el autocompletado sugiriendonos la variable más apropiada para pasar como parámetro a la función. Por otro lado, Typescript es lo suficientemente inteligente para inferir el tipo sin indicarselo explícitamente.

typescript-fundamentos

Además de los tipos String y Number, TypeScript también admite los siguientes tipos básicos:

  • Boolean: tipo de dato logico que representa verdadero o falso.
  • Array: tipo de dato estructurado que permite almacenar una colección de elementos.
  • Tuple: similar al array, pero con un número fijo de elementos escritos.
  • Enum: representa al tipo enumeración. Una enumeración es una forma de dar nombres descriptivos a los conjuntos de valores numéricos
  • Any: indica que la variable puede ser de cualquier tipo. Es muy útil a la hora de trabajar con librerías externas.
  • Void: indica que una función no devolverá ningún valor.
  • Never: este tipo representa el tipo de valores que nunca se producen. Por ejemplo para indicar que una función siempre arroja una excepción o que nunca termina su ejecución.

Echemos un vistazo al siguiente codigo para obtener una vision general de lo que Typescript nos permite hacer con los tipos básicos:

// 1 - declaracion del tipo
type Ranking = [number, string, boolean];

// 2 - definición de variables
let position: number;
let playerName: string;
let finishedGame: boolean;
let ranking: Ranking;
let hallOfFame: Array<Ranking> = [];

// 3 - crea un ranking
position = 1;
playerName = "Bruno Krebs";
finishedGame = true;
ranking = [position, playerName, finishedGame];
hallOfFame.push(ranking);

// 4 - crea otro ranking
position = 2;
playerName = "Maria Helena";
finishedGame = true;
ranking = [position, playerName, finishedGame];
hallOfFame.push(ranking);

// 5 - define una funcion que recorre todos los rankings
function printRankings(rankings: Array<RankingTuple>): void {
  for (let ranking of rankings) {
    console.log(ranking);
  }
}

// 6 - llama a la función
printRankings(hallOfFame);

Si quieres continuar profundizando en el sistema de tipos de typescript te recomiendo que eches un vistazo a la documentación oficial.

Estructuras iterativas

En typescript tenemos podemos hacer uso de dos tipos de bucles diferentes for ... in y for .. of. For... in es una proviene de versiones antiguas de javascript el cual nos permite recorrer objetos iterables obteniendo sus indices. En cambio, For...of es una caracteristica introducida en ES6, la cual nos permite recorrer colecciones obteniendo su valor, veamos las diferencias con un ejemplo:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

Modulos en typescript

Otra de las características de Typescript es heredada de ECMAScript 2015 la posibilidad de crear módulos, loc cuales no son más que una forma de encapsular código en su propio ámbito. Nos permiten agrupar nuestro código en diferentes ficheros, permitiéndonos exportarlos y utilizarlos donde los necesitemos. Esto nos facilita la tarea de crear software más ordenado y por ende más escalable y mantenible.

Continuando con el ejemplo de la sección anterior, si quisieramos exportar el tipo Ranking y la función printRankings(), tan solo tendríamos que añadirle la palabra reservada export antes de la definición de los mismos:

export type RankingTuple = [number, string, boolean];

export function printRankings(rankings: Array<RankingTuple>): void {
  for (let ranking of rankings) {
    console.log(ranking);
  }
}

Para importarlos en otro fichero tan solo nos bastaría con lo siguiente:

import {RankingTuple, printRankings} from './myRankingModule.ts';

Clases y objetos en Typescript

Un objeto es una entidad que agrupa un estado y una funcionalidad relacionada,una clase, no es más que una plantilla genérica a partir de la cuál instanciamos los objetos. Dicho de otra manera, una clase es una abstracción en la que se define el comportamiento que va a tener el objeto.

Las clases en Typescript son muy similares a lo que nos ofrecen otros lenguajes de orientación a objetos tradicionales, esto nos ayudará a modularizar nuestro código y a simplificar el desarrollo. Veamos con un ejemplo como definir una clase:

class Employee {
    //atributo accesible desde fuera de la clase
    public name : string;
    //atributos accesible desde clases que hereden de Employee
    protected age: number;
    //access only inside the Employee class
    private mobile : string;

    constructor(name:string ,age:number, mobile:string){
        this.name = name;
        this.age = age;
        this.mobile = mobile;
    }
    getName(){
       return this.name;
    }

    setName(name:string){
       this.name = name;
    }
    getAge(){
       return this.age;
    }

    setAge(age:number){
       this.age = age;
    }

    getMobile(mobile:string){
       this.mobile = mobile;
    }
}

Métodos accesores (Getters y Setters)

Como sabemos, los métodos get y set, también conocidos como métodos accesores, son simples funciones que usamos en las clases para mostrar (get) o modificar (set) el valor de un atributo. Normalmente los escribimos como "get" o "set" seguido del nombre de la propiedad a la que queremos acceder, por ejemplo: getName(). En Typescript se puede hacer de esta forma o haciendo uso de las palabras reservadas get o set delante del nombre de la función:

class Actor {
    private _name : string;
    constructor(_name:string){
        this._name = _name;
    }
    set name (value: string){
        this._name = value;
    }
    get name (){
        return this._name;
    }
}

let actor = new Actor('Haider Malik');
console.log(actor.name);
//set
actor.name = 'Jane Doe';
console.log(actor.name);

Herencia en typescript

Otro elemento fundamental en la OO es la herencia, la cual nos permite extender la funcionalidad nuestra clase herendando de una clase padre. La clase hija hereda todos los miembros de su clase base y puede sobreescribir todos aquellos métodos y/o propiedades públicos o protegidos.

class Manager extends Employee {
   constructor(name : string, age: number , mobile : string){
       super(name,age,mobile);
       this.age = 24;
   }
}

let manager = new Manager('Jane',23, '0343–23332233');
console.log(manager.getName());
console.log(manager.getAge());

Clases abstractas

Este tipo de clases no pueden ser instanciadas ya que se usan para definir comportamientos independientemente de su concreción. Su implementación en typescript es similar a la de una clase normal con la diferencia que hay que anteponer el termino abstract antes de declararlas.

abstract class Product {
    productName : string = "Default";
    price :number = 1000;
    abstract changeName(name: string): void;

    calcPrice(){
        return this.price;
    }
}

class Mobile extends  Product {
    changeName(name : string) : void {
        this.productName = name;
    }
}
let mobile = new Mobile();
console.log(mobile.productName);
mobile.changeName('Galaxy');
console.log(mobile.productName);

Aparte de las ventajas comentadas, Typescript es capaz de utilizar todas las características de ECMAScript y de la API de JavaScript. Esto hace posible que TypeScript no solo sea compatible con la sintaxis y los tipos estáticos de Java o C#, sino con las funciones lambda y las promesas de ECMAScript 2015, entre otros.

Otras características de TypeScript

Typescript soporta además otras características muy interesantes como son:

  • Interfaces
  • Mixins
  • Genéricos
  • Namespaces
  • Decoradores
  • Soporte JSX Aunque algunas de estas características están fuera del ámbito de este artículo, publicaré más entradas sobre Typescript. En el siguiente vistazo veremos interfaces y genéricos, los cuales son los pilares básicos del diseño orientado a contratos. Si te ha gustado esta introducción al lenguaje de programación Typescript compártelo en las redes sociales.

Al suscribirte a la newsletter comparto contigo los 10 libros más importantes de programación. Los que sin duda todo dev debería leer al menos una vez...

Quizás te interese

Union types y pattern matching con TypeScript.

Union types y pattern matching con TypeScript.

Tutorial React.js: introducción en 5 minutos

Tutorial React.js: introducción en 5 minutos