Desde los años noventa, Javascript cobró popularidad por ser el lenguaje que revolucionó las páginas de internet al darles funcionalidad. Javascript empezó como el código que le daba vida a HTML para dejar en el pasado a las páginas web estáticas. Desde entonces evolucionó. Ahora es posible ejecutar código Javascript en un entorno de servidor.
Posteriormente, Microsoft se encargó de mejorarlo hasta convertirlo en TypeScript, cuya base es el tipado de datos. Poco a poco se ha ido popularizando y se ha combinado para ser la base de los frameworks más populares para desarrollo web como React, Vue y Angular.
En este tema aprenderás lo básico para realizar un programa en Typescript.
Tipos básicos y conceptos generales
TypeScript es un lenguaje de programación que, al igual que los demás, ocupa diferentes tipos de datos. Está basado en JavaScript. Los tipos de datos son la principal característica del lenguaje, ya que maneja un tipo estático, es decir, no se pueden cambiar en tiempo de compilación.
De acuerdo con Rozentals (2019), cambiar el tipo de una variable en tiempo de ejecución puede ser algo muy peligroso y causar problemas incalculables. TypeScript introduce una sintaxis muy simple para comprobar el tipo de un tema de objeto. Esta sintaxis ha sido reverenciada como azúcar sintáctico o, más formalmente, anotaciones de tipo.
Los tipos básicos son “boolean, number, string, array, tuple, Object, object, null, undefined, {}, y enum” (Jansen, 2018).
Especifica si una variable es verdadera o no. Únicamente puede tener dos valores: true y false.
let flagTrue: boolean = true; let flagFalse: boolean = false; |
Tabla 1. Ejemplo de definición de variable de tipo boolean.
Especifica los tipos de datos que son números y les asigna valores de coma flotante al igual que en JavaScript.
let numero: number = 2; |
Tabla 2. Ejemplo de definición de variable de tipo number.
Representa cualquier texto.
let mensaje: string = "Hola mundo"; |
Tabla 3. Ejemplo de definición de variable de tipo string.
Es el tipo superior, es decir, todos los tipos en TypeScript son subtipos de any, comprueba y representa todos los tipos posibles. Es posible cambiar el tipo de dato a lo largo del programa.
let desconocido: any = "Hola"; //Se le asigna valor string desconocido = 6; //ahora es number desconocido = true; //ahora es boolean |
Tabla 4. Ejemplo de definición de variable de tipo any.
Los tipos null (nulo) o undefined (indefinido) son subtipos de todos los demás tipos. Eso significa que “puedes asignar nulo e indefinido a algo como un número” (Jansen, 2018).
let numeroNulo: Number = null; let indefinido: Number = undefined; |
Tabla 5. Ejemplo de definición de variable de tipo null y undefined.
El uso de los tipos de datos es más estricto en TypeScript, a diferencia de Javascript. En un proyecto a gran escala, representa una ventaja, ya que se podrán identificar errores y comportamientos diferentes a los esperados.
Objetos, arreglos e interfaces
Jansen (2018) indica que object es un tipo de datos que representa cualquier tipo no primitivo. Los siguientes tipos se consideran tipos primitivos en JavaScript: booleano, número, cadena, símbolo, nulo e indefinido. El tipo Object describe la funcionalidad que es común en todos los objetos.
const pelicula = { nombre: 'Toy Story', clasificacion: 'Infantil/Comedia', detalles: { director: 'John Lasseter', anio: 1995, musica: 'Randy Newman' } }; |
Tabla 6. Ejemplo de definición de variable de tipo objeto.
Los arreglos son un tipo de dato para especificar colecciones de valores. Existen dos estilos de sintaxis para un array genérico.
// Primer estilo de sintaxis let lista: number[] = [1, 2, 3];
// Segundo estilo de sintaxis let lista2: Array<number> = [1, 2, 3]; |
Tabla 7. Ejemplo de definición de variable de tipo array.
También existe un tipo de datos que representa una matriz con un número fijo de elementos con diferentes tipos; se llama tupla. Por ejemplo, podemos representar un valor como un par de una cadena y un número.
let miTupla: [string, number]; miTupla = ["hola", 1]; |
Tabla 8. Ejemplo de definición de variable de tipo tupla.
En caso de que requieras añadir significado a un conjunto de valores, puedes utilizar enum (enumeración). Las enumeraciones pueden ser numéricas o basadas en texto.
enum Color {Rojo, Verde, Azul}; let c: Color = Color.Azul; |
Tabla 9. Ejemplo de definición de variable de tipo number.
Algunas ocasiones necesitarás una colección de datos de un tipo predefinido, es por ello que ocupamos las interfaces y se pueden definir de la siguiente forma:
interface Persona { nombre: string; edad?: number; email: string; }
const persona: Persona = { nombre: 'Juan', edad: 18, email: 'juan@mail.com' } |
Tabla 10. Ejemplo de interface.
En el ejemplo anterior, declaramos la interface y posteriormente una constante llamada “persona” que era de tipo de dato “Persona”, que se definió como interface. También puedes observar que “edad” tiene un signo “?”, esto sirve para indicar a TypeScript que es opcional. Podemos definirlo en la constante “persona” o no.
Funciones
En algunas ocasiones vas a necesitar reutilizar un fragmento de código más de una vez, por lo que repetir el código no representa una buena práctica, por lo que puedes necesitar las funciones.
“Las funciones son el medio principal de pasar datos en JavaScript. TypeScript le permite especificar los tipos de los valores de entrada y salida de las funciones” TypeScript (2021).
Una función se ocupa de la siguiente forma:
//Función con parámetro, pero no retorna dato function saluda(name: string) { console.log('Hola, ' + name.toUpperCase()); }
//Función sin parámetro regresa number function dameNumero(): number { const num = 10; return num; }
saluda('Juan'); console.log('Número ' + dameNumero()); |
Tabla 11. Ejemplo de funciones.
Existe una forma de reducir el código las funciones; a estas se les llama funciones de flecha. Y como se muestra en el siguiente ejemplo, las funciones hacen lo mismo, calculan la sumatoria entre dos números. La función “suma” es una función normal y la función “suma2” es una función de flecha.
function suma(a: number, b: number): number { return a + b; }
let suma2 = (a: number, b: number): number => a + b;
console.log('Suma de 3 + 5 = ' + suma(3, 5)); console.log('Suma de 3 + 5 = ' + suma2(3, 5)); |
Tabla 12. Ejemplo de funciones de flecha.
Desestructuración de objetos, arreglos y argumentos
El concepto de la desestructuración de objetos habilita la extracción de los objetos fácilmente. Sirve para extraer las propiedades que interesan realmente de una forma sencilla y rápida.
interface Pelicula { nombre: string; clasificacion: string; detalles: Detalles; } interface Detalles { director: string; anio: number; musica: string; }
const pelicula: Pelicula = { nombre: 'Toy Story', clasificacion: 'Infantil/Comedia', detalles: { director: 'John Lasseter', anio: 1995, musica: 'Randy Newman', }, };
const { nombre, clasificacion, detalles } = pelicula; const { musica } = detalles;
console.log('Nombre de película: ' + nombre); console.log('Clasificación: ' + clasificacion); console.log('Música: ' + musica); |
Tabla 13. Ejemplo de desestructuración de objetos.
De igual forma también podemos realizar desestructuración, pero de arreglos. Nos sirve para obtener las propiedades por posición, porque a diferencia de los objetos, en los arreglos no tenemos nombre para identificar a cada elemento. Recordemos que los arreglos, como cualquier lenguaje de programación, inician con el índice 0.
const toyStory: string[] = ['Woody', 'Buzz', 'Rex']; const [toy1, toy2, toy3] = toyStory;
console.log('Posición 0:', toy1); // Posición 0: Woody console.log('Posición 1:', toy2); // Posición 1: Buzz console.log('Posición 2:', toy3); // Posición 2: Rex |
Tabla 14. Ejemplo de desestructuración de arreglos.
En caso de que necesites únicamente un elemento en específico, puedes obtenerlo sin necesidad de asignar un nombre a las variables anteriores y se deja el espacio vacío.
const toyStory: string[] = ['Woody', 'Buzz', 'Rex']; const [, , toy3] = toyStory; console.log('Posición 2:', toy3); // Posición 2: Rex |
Tabla 15. Ejemplo de desestructuración de arreglos de elemento específico.
Otro tipo de desestructuración es la de argumentos, que te sirve para obtener elementos específicos desde los argumentos de una función. Lo observamos en el siguiente ejemplo:
interface Persona { nombre: string; apellido: string; } const persona1: Persona = { nombre: 'Juan', apellido: 'López', };
const persona2: Persona = { nombre: 'Sara', apellido: 'Rivera', };
function obtenerApellidos(arreglo: Persona[]): string { let apellidos = 'Apellidos: '; arreglo.forEach(({ apellido }) => { apellidos += apellido + ','; }); return apellidos; }
const arregloPersonas = [persona1, persona2]; console.log(obtenerApellidos(arregloPersonas)); //Apellidos: López,Rivera |
Tabla 16. Desestructuración de argumentos.
Como habrás notado, la desestructuración es muy útil cuando queremos acceder a elementos en específico.
Importaciones y exportaciones
Las importaciones y exportaciones en TypeScript, nos ayuda a ocupar funciones, objetos, constantes, variables, interfaces, etcétera, entre un archivo y otro. Por ejemplo, si has creado un archivo llamado “utils” que contiene todo el código que necesitas reutilizar en otros archivos, ocuparás la exportación que se define con la palabra reservada export en cada elemento que deseas exportar.
Observa el siguiente ejemplo:
export interface Nombre { nombre: string; apellidoPaterno: string; apellidoMaterno: string; }
export const pi = 3.141592;
export function agregaIVA(precio: number): number { return precio * 1.16; }
export const multiplica = (a: number, b: number): number => { return a * b; }; |
Tabla 17. Ejemplo de exportación.
Para poder acceder a los elementos del ejemplo anterior desde otro archivo se debe realizar una importación como se muestra en la primera línea del siguiente ejemplo:
import { agregaIVA, multiplica, pi, Nombre } from './utils';
const alumno: Nombre = { nombre: 'Fernando', apellidoPaterno: 'García', apellidoMaterno: 'Trejo', };
console.log(alumno); // { nombre: 'Fernando', apellidoPaterno: 'García', apellidoMaterno: 'Trejo' } console.log('Precio con IVA: ' + agregaIVA(500)); //Precio con IVA: 580 console.log('3x5=' + multiplica(3, 5)); // 3x5=15 console.log('Valor de PI ' + pi); // Valor de PI 3.141592 |
Tabla 18. Ejemplo de importación.
Constructores
ECMAScript 6, “agrega orientación a objetos basada en clases a JavaScript y, dado que TypeScript incluye todas las características disponibles en ES6” (Jansen, 2018), por lo tanto, puedes ocupar la orientación de objetos basada en clases.
En Typescript puedes tener todas las funciones y propiedades del paradigma orientado a objetos. Es por lo que puedes definir clases y crear sus atributos, métodos y constructores. Los atributos son las propiedades, los métodos son pequeñas funciones dentro de las clases y el constructor es un método que se llama cuando se crea la instancia de la clase. A continuación, un ejemplo:
class Mascota { public animal: string; public nombre: string; public edad: number;
constructor(animal: string, nombre: string, edad: number) { this.animal = animal; this.nombre = nombre; this.edad = edad; }
public obtenerDatos() { return `Mi mascota se llama ${this.nombre}, es un ${this.animal} que tiene ${this.edad} años.`; } } const mascota = new Mascota('perro', 'Drako', 3); console.log(mascota.obtenerDatos()); |
Tabla 19. Ejemplo de una clase con atributos y constructor.
Como verás, puedes optimizar tu código con el uso de las clases y los constructores.
Decoradores
De acuerdo con TypeScript (2021), un decorador es un tipo especial de declaración que puede adjuntarse a una declaración de clase, método, accesorio, propiedad o parámetro. Los decoradores se identifican como @expresión, donde expresión debe evaluarse a una función que será llamada en tiempo de ejecución con información sobre la declaración decorada. Los decoradores pueden cambiar las clases cuando se está ejecutando el programa.
function cambiarPelicula(data: string) { return function <T extends { new (...args: any[]): {} }>(constructor: T) { return class extends constructor { name = data; }; }; }
@cambiarPelicula('Avengers') class Film { name: string; constructor(name: string) { this.name = name; }
reproductor() { console.log(`${this.name} se está reproduciendo`); } }
new Film('ToyStory').reproductor(); // Avengers se está reproduciendo! |
Tabla 20. Ejemplo de decorador de clase.
TypeScript es un lenguaje de programación que ha mejorado las funciones de JavaScript. Al compilar TypeScript se crea código en Javascript, pero mejorado que se vuelve una ventaja en códigos extensos y proyectos a gran escala.
¿Has visto cómo se transforma tu código de TypeScript en Javascript?
¿Te has preguntado cómo te puede ayudar el entender el paradigma orientado a objetos entender varios lenguajes de programación fácilmente?
¿Has pensado en las ventajas de programar con TypeScript?
¿Qué frameworks ocupan TypeScript?
Asegúrate de: