1

Fundamentos de TypeScript

TypeScript es un lenguaje de programación desarrollado y mantenido por Microsoft. Es un superset de JavaScript que agrega tipado estático opcional, y características orientadas a objetos. TypeScript permite a los desarrolladores escribir código más robusto y mantenible, mejorando la experiencia de desarrollo a través de herramientas de autocompletado, verificación de tipos en tiempo de compilación y soporte para programación modular.

Características principales de TypeScript


  • Tipado Estático: TypeScript permite especificar tipos de datos (como string, number, boolean, etc.) para variables, parámetros y funciones. Esto ayuda a detectar errores en tiempo de compilación en lugar de en tiempo de ejecución, lo que puede hacer que el código sea más seguro y fácil de mantener.
  • Superset de JavaScript: Todo código JavaScript válido es también código TypeScript válido. Esto significa que puedes usar TypeScript en proyectos existentes de JavaScript sin necesidad de reescribir todo el código.
  • Orientado a Objetos: TypeScript soporta características de Programación Orientada a Objetos (OOP), como clases, interfaces y herencia, lo que facilita la organización del código y su reutilización.
  • Interoperabilidad: TypeScript se puede integrar fácilmente con bibliotecas y frameworks de JavaScript, como React, Angular y Vue.js.
  • Compilación a JavaScript: TypeScript se compila a JavaScript puro, lo que significa que puedes ejecutar código TypeScript en cualquier entorno que soporte JavaScript, como navegadores web o servidores Node.js.
  • Características Avanzadas: TypeScript incluye características como generics, enums, y tipos avanzados (uniones, intersecciones), lo que permite una mayor flexibilidad y expresividad en el código.

TypeScript es ampliamente utilizado en el desarrollo de aplicaciones web frontend y backend, especialmente en proyectos grandes y complejos donde la seguridad de tipos y la mantenibilidad del código son cruciales.

Variables y Constantes

Para declarar una variable o constante, se utiliza la palabra clave let o const seguida del nombre de la variable, un símbolo de dos puntos (:) para especificar el tipo (opcional), y luego se asigna un valor con el símbolo de igual (=)

letnombreVariable: tipo = valor;
constnombreConstante: tipo = valor;

Tipos de Datos

Tipos Inferidos

Se puede omitir el tipo de dato, de esta manera TypeScript va a inferir el tipo a partir del valor asignado:

let edad = 30; // TypeScript infiere que es un numberconst saludo = "Hola"; // TypeScript infiere que es un string

Tipos Primitivos

Tipo de DatoDescripciónEjemplo
numberRepresenta tanto enteros como números de punto flotante.let edad: number = 30;
stringRepresenta texto.let nombre: string = "Carlos";
booleanRepresenta un valor verdadero o falso.let esDesarrollador: boolean = true;
nullRepresenta la ausencia intencionada de un valor.let valorNulo: null = null;
undefinedIndica que una variable no ha sido inicializada.let valorIncierto: undefined;

Ejemplo:

constname: string = "Carlos";
letage: number = 30;
letisActive: boolean = true;

Tipos de Estructura

Tipo de DatoDescripciónEjemplo
arrayColección de valores del mismo tipo.let numeros: number[] = [1, 2, 3];
arrayColección de valores del mismo tipo.let nombres: Array<string> = ["Carlos", "Ana", "Luis"];
tupleArray con un número fijo de elementos de diferentes tipos.let persona: [string, number] = ["Carlos", 30];

Arrays

TypeScript permite dos formas de declarar arrays: usando la notación de corchetes ([]) o la clase Array.

  • Usando corchetes:

    const nombreArray **:** tipo[] = [item1, item2, item3];
    
  • Usando la clase Array:

    const nombre-array : Array<tipo> = [item1, item2, item3]; // Array de strings
    

    Ejemplo:

    letnumeros: number[] = [1, 2, 3]; // Array de numerosletnombres: Array<string> = ["Carlos", "Ana", "Luis"]; // Array de strings

Tuples

Las tuples son arrays con un número fijo de elementos de diferentes tipos. Esto permite representar datos más complejos de manera estructurada.

Para declarar una tuple, se utiliza la notación de corchetes ([]) para especificar los tipos de cada elemento en la tuple:

const nombre-tuple: [tipo1, tipo2] = [item1, item2];

Ejemplo:

const persona: [string, number] = ["Carlos", 30]; // Tuple con un stringy un number

🚨

  • Arrays: Son colecciones de elementos del mismo tipo, y se pueden modificar dinámicamente (agregar y eliminar elementos).
  • Tuples: Son arrays de longitud fija con tipos de datos diferentes en cada posición. Son útiles para representar estructuras de datos más complejas y están limitadas en cuanto a la modificación de su contenido.

Tipos Especiales

Tipo de DatoDescripciónEjemplo
anyPermite almacenar cualquier tipo de valor.let dato: any = "Hola";
voidTipo de retorno de funciones que no devuelven un valor.function mostrarMensaje(): void { console.log("Hola"); }

El tipo any en TypeScript es un tipo especial que permite almacenar valores de cualquier tipo. Es útil en situaciones donde no se puede determinar el tipo de una variable en el momento de la escritura, o cuando se está trabajando con datos provenientes de fuentes externas, como APIs, donde los tipos pueden ser dinámicos o desconocidos.

Ventajas del tipo any

  • Flexibilidad: Permite la asignación de diferentes tipos de datos a una variable sin restricciones.
  • Interoperabilidad: Facilita la integración con bibliotecas JavaScript existentes donde los tipos pueden no estar claramente definidos.

Desventajas del tipo any

  • Pérdida de Tipado Estático: Al usar any, se pierde gran parte de la ventaja que ofrece TypeScript, que es la verificación de tipos en tiempo de compilación. Esto puede llevar a errores en tiempo de ejecución que podrían haberse evitado con un tipado más estricto.
  • Menos Intellisense: La autocompletación y la asistencia del editor se ven reducidas al usar any, ya que TypeScript no puede inferir los métodos o propiedades disponibles.
  • Dificultad de Mantenimiento: El uso excesivo de any puede resultar en un código más difícil de leer y mantener, ya que no proporciona información clara sobre qué tipo de datos se espera.

🚨

¿Es mala práctica usar any?

  • Uso Moderado: Usar any ocasionalmente puede ser aceptable, especialmente en etapas tempranas de desarrollo o cuando se integra con librerías externas donde los tipos no están definidos. Sin embargo, debe ser un uso limitado.
  • Mejores Alternativas: En lugar de usar any, se recomienda utilizar tipos más específicos o, si es necesario, definir tipos personalizados que describan la estructura esperada de los datos.

Union Types

Los Union Types (tipos de unión) en TypeScript son una característica que permite a una variable aceptar múltiples tipos de datos. Esto significa que puedes definir un tipo que puede ser uno de varios tipos diferentes. Esto es útil cuando una variable puede tener diferentes tipos de valores en diferentes contextos.

La sintaxis para definir un Union Type utiliza el operador de pipe (|).

letvalor: string | number; // `valor` puede ser string o number

valor = "Hola"; // Válido
valor = 42;     // También válido// valor = true; // Error, ya que `boolean` no es parte del tipo

Ventajas de los Union Types


  • Flexibilidad: Permiten que una variable tenga múltiples tipos, lo que es útil en situaciones donde los valores pueden variar.
  • Claridad: Hacen explícito qué tipos son aceptables, lo que puede mejorar la legibilidad y mantenimiento del código.
  • Tipo Seguro: Aumentan la seguridad del tipo al permitir que TypeScript verifique que solo se asignen valores de los tipos permitidos.

Alias de Tipo

Los alias de tipo son una forma de dar un nombre a un tipo que puede ser utilizado en varias partes de tu código. Esto es especialmente útil para simplificar tipos complejos o para dar un nombre más descriptivo a un tipo.

Para crear un alias de tipo, se utiliza la palabra clave type seguida del nombre del alias y el tipo que deseas representar.

typeNombreAlias = {
    propiedad1: Tipo1;
    propiedad2: Tipo2;
    propiedadOpcional?: Tipo3;  // Propiedad opcional
};

Ejemplo:

type Persona = {
    nombre: string;
    edad: number;
    activo: boolean;
    direccion?: string;  // Propiedad opcional
};

letempleado: Persona = {
    nombre: "Carlos",
    edad: 37,
    activo: true
};

Alias de Tipo con Unión

Los alias de tipo también se pueden utilizar para crear tipos de unión, lo que significa que un valor puede ser uno de varios tipos diferentes.

type ID = number | string;

let id1: ID = 123;
let id2: ID = "abc";

Tipos Literales

Un tipo literal restringe los valores posibles de una variable a un conjunto específico de valores. Es especialmente útil cuando quieres definir un conjunto limitado de valores válidos para una propiedad o variable.

typeNombreTipoLiteral= "ValorLiteral1" | "ValorLiteral2" | "ValorLiteral3";

Ejemplo:

typeEstado= "activo" | "inactivo" | "pendiente";

let estadoActual: Estado = "activo";

Combinación de Alias y Tipos Literales

Se pueden combinar alias de tipo con tipos literales para crear estructuras de datos más complejas.

Ejemplo:

type MetodoPago = "tarjeta" | "efectivo" | "transferencia";

type Pedido = {
    id: number;
    metodo: MetodoPago;
};

letpedido1: Pedido = {
    id: 1,
    metodo: "tarjeta"
};

pedido1.metodo = "bitcoin"; 
		// Error: Type '"bitcoin"' is not assignable to type 'MetodoPago'.

Objetos

Un objeto en TypeScript se puede definir de manera similar a JavaScript, pero con la posibilidad de especificar los tipos de sus propiedades. Se pueden especificar los tipos de las propiedades de un objeto utilizando anotaciones de tipos. Esto asegura que las propiedades tengan los tipos correctos.

Sintaxis Básica

constpersona: { propiedad1: Tipo1, propiedad2: Tipo2, propiedad3: Tipo3; } = {
    propiedad1: Tipo1;
    propiedad2: Tipo2;
    propiedad3: Tipo3; 
};

Ejemplo:

letpersona: { nombre: string, edad: number, activo: boolean } = {
    nombre: "Carlos",
    edad: 30,
    activo: true
};

Interfaces

Cuando se trabaja con objetos más complejos o cuando se quiere reutilizar la estructura de un objeto en varias partes del ódigo, es mejor usar interfaces. Una interface define la estructura de un objeto, lo que facilita la lectura y el mantenimiento del código.

interface NombreInterfaz {
		propiedad1: Tipo1;
    propiedad2: Tipo2;
    propiedad3: Tipo3; 
}

constnombreObjeto: NombreInterfaz = {
		propiedad1: Tipo1;
    propiedad2: Tipo2;
    propiedad3: Tipo3; 
}

Ejemplo:

interface Persona {
    nombre: string;
    edad: number;
    activo: boolean;
}

constempleado: Persona = {
    nombre: "Ana",
    edad: 25,
    activo: true
};

Propiedades de Solo Lectura (readonly)

TypeScript permite declarar propiedades como de solo lectura utilizando la palabra clave readonly. Esto significa que una vez asignado un valor a la propiedad, no puede cambiar.

Ejemplo:

interface Libro {
    titulo: string;
    readonly autor: string;
}

constlibro: Libro = {
    titulo: "El Quijote",
    autor: "Miguel de Cervantes"
};

// libro.autor = "Otro autor"; // Error: No se puede modificar una propiedad readonly

Index Signatures

Los tipos de índice permiten que un objeto tenga un número dinámico de propiedades de tipos específicos. Es útil cuando no sabes cuántas propiedades tendrá un objeto, pero sí conoces el tipo de esas propiedades.

interfaceNombreInterfaz {
    [clave: TipoClave]: TipoValor;
}

const nombreObjeto: NombreInterfaz = {
		clave-TipoClave: TipoValor;
    clave-TipoClave: TipoValor;
    clave-TipoClave: TipoValor; 
}

Ejemplo:

interface Diccionario {
    [clave: string]: string;
}

letmiDiccionario: Diccionario = {
    casa: "house",
    perro: "dog",
    gato: "cat"
};

console.log(miDiccionario["casa"]); // "house"

Funciones

Al igual que en JavaScript, las funciones en TypeScript pueden aceptar parámetros, devolver valores y ser pasadas como argumentos a otras funciones. Sin embargo, TypeScript agrega características adicionales, como la capacidad de especificar tipos para los parámetros y el valor de retorno.

Sintaxis Básica

La sintaxis para declarar una función en TypeScript es similar a JavaScript, pero con la adición de tipos:

Función explícita

functionnombreFuncion(parametro1: tipo1, parametro2: tipo2): tipoRetorno {
    // Cuerpo de la función
}

Función Flecha

const nombreFuncion = (parametro1: tipo1, parametro2: tipo2): tipoRetorno => {
    // Cuerpo de la función
};

Retorno de la Funciones

Tipo de RetornoDescripciónEjemplo
numberLa función devuelve un número.function add(x: number, y: number): number { return x + y; }
stringLa función devuelve una cadena de texto.function greet(name: string): string { return "Hola, " + name; }
booleanLa función devuelve un valor booleano (true o false).function isEven(num: number): boolean { return num % 2 === 0; }
voidLa función no devuelve ningún valor. realiza acciones sin devolver un valor.function log(message: string): void { console.log(message); }
nullLa función devuelve un valor nulo.function getNull(): null { return null; }
undefinedLa función devuelve indefinido (puede ser implícito si no se retorna nada).function doNothing(): undefined { }
arrayLa función devuelve un arreglo de elementos de un tipo específico.function getNumbers(): number[] { return [1, 2, 3]; }
tuplaLa función devuelve una tupla con elementos de diferentes tipos.function getUser(): [string, number] { return ["Carlos", 30]; }
objectLa función devuelve un objeto con propiedades específicas.function getUser(): { name: string; age: number } { return { name: "Carlos", age: 30 }; }
uniónLa función puede devolver más de un tipofunction getValue(isString: boolean): string
interfazLa función devuelve un objeto que cumple con una interfaz específica.interface User { name: string; age: number; } function getUser(): User { return { name: "Carlos", age: 30 }; }

Propiedades y Parámetros Opcionales

En TypeScript, el signo de interrogación (?) se utiliza para declarar propiedades y parámetros opcionales. Esto permite que ciertos atributos de una clase o funciones no sean obligatorios, brindando mayor flexibilidad al trabajar con objetos y funciones.

Propiedades Opcionales

Al declarar una propiedad en una interfaz o clase, se puede usar el ? para indicar que la propiedad es opcional. Esto significa que no es necesario proporcionar un valor para esa propiedad al crear una instancia del objeto. Si no se proporciona, el valor de la propiedad será undefined.

Ejemplo:

interface Usuario {
    nombre: string;
    edad?: number; // Propiedad opcional
}

constusuario1: Usuario = { nombre: "Carlos" }; // edad es opcionalconstusuario2: Usuario = { nombre: "Ana", edad: 25 }; // edad está presente

Parámetros Opcionales y Valores por Defecto

Los parámetros de una función también pueden ser marcados como opcionales usando ?. Esto permite que la función se llame sin necesariamente proporcionar un argumento para ese parámetro.

Ejemplo:

functionsaludar(nombre: string, saludo?: string): string{
    return`${saludo || "Hola"}, ${nombre}!`;
}

console.log(saludar("Carlos")); // "Hola, Carlos!"console.log(saludar("Ana", "Buenos días")); // "Buenos días, Ana!"

También se puede proporcionar un valor por defecto a un parámetro:

functionmultiplicar(a: number, b: number = 1): number{
    return a * b;
}

console.log(multiplicar(5)); // 5console.log(multiplicar(5, 2)); // 10

Optional Chaining

El encadenamiento opcional (?.) es una característica que permite acceder a propiedades de un objeto de forma segura, evitando errores si la propiedad es null o undefined. Si la propiedad no existe, se devuelve undefined en lugar de lanzar un error.

Ejemplo:

const usuario = { nombre: "Carlos", direccion: { ciudad: "Madrid" } };

console.log(usuario.direccion?.ciudad); // "Madrid"console.log(usuario.telefono?.numero); // undefined, no arroja error

El operador de coalescencia nula

Aunque no está directamente relacionado con el uso de ?, el operador ?? se usa para asignar un valor por defecto si el valor de la izquierda es null o undefined.

const value = null;
constresult = value ?? "Default Value"; // result será "Default Value"
Escribe tu comentario
+ 2