TypeScript: Dominando el Tipado Estático
Aprende TypeScript y haz tu código JavaScript más seguro y robusto
TypeScript: Dominando el Tipado Estático
TypeScript es un superset tipado de JavaScript que compila a JavaScript puro. Desarrollado por Microsoft y lanzado en 2012, añade tipado estático opcional y características avanzadas de orientación a objetos a JavaScript, haciendo el desarrollo de aplicaciones a gran escala más seguro y productivo.
Nota: TypeScript está construido sobre JavaScript. Si necesitas revisar los fundamentos, consulta nuestra Guía de JavaScript antes de continuar.
¿Por qué TypeScript?
TypeScript ofrece beneficios significativos para equipos y proyectos de cualquier tamaño:
- Detección de Errores en Tiempo de Compilación - Encuentra bugs antes de ejecutar el código
- IntelliSense Mejorado - Autocompletado inteligente y documentación inline
- Refactorización Segura - Renombra variables y funciones con confianza
- Documentación Implícita - Los tipos sirven como documentación viva
- Escalabilidad - Mantén proyectos grandes organizados y seguros
- Adopción Gradual - Migra desde JavaScript incrementalmente
Tipos Básicos
Tipos Primitivos
// Tipos simples
let nombre: string = "María";
let edad: number = 25;
let activo: boolean = true;
let nulo: null = null;
let indefinido: undefined = undefined;
// Arrays
let numeros: number[] = [1, 2, 3, 4, 5];
let nombres: Array<string> = ["Ana", "Pedro", "Carlos"];
// Tuplas
let coordenada: [number, number] = [10, 20];
let registro: [string, number, boolean] = ["María", 25, true];
// Enum
enum Estado {
Pendiente = "PENDIENTE",
Aprobado = "APROBADO",
Rechazado = "RECHAZADO"
}
let estadoPedido: Estado = Estado.Pendiente;
Tipos Avanzados
// Union Types
type ID = string | number;
let userId: ID = "abc123";
userId = 42; // También válido
// Intersection Types
type Persona = { nombre: string };
type Empleado = { cargo: string };
type EmpleadoPersona = Persona & Empleado;
// Literal Types
type Direccion = "norte" | "sur" | "este" | "oeste";
let direccion: Direccion = "norte";
// Template Literal Types
type NombreEvento = `on${Capitalize<string>}`;
// Nullable Types
let valorOpcional: string | null = null;
valorOpcional = "Valor definido";
Interfaces vs Types
// Interface - ideal para objetos y clases
interface Usuario {
id: number;
nombre: string;
email: string;
readonly creadoEn: Date;
direccion?: Direccion; // Propiedad opcional
}
interface Direccion {
calle: string;
ciudad: string;
pais: string;
}
// Extensión de interface
interface Admin extends Usuario {
permisos: string[];
nivel: "junior" | "senior" | "master";
}
// Type alias - más flexible
type Resultado<T> =
| { exito: true; datos: T }
| { exito: false; error: string };
type Callback<T> = (datos: T) => void;
Generics
// Función genérica
function primero<T>(array: T[]): T | undefined {
return array[0];
}
const primerNumero = primero([1, 2, 3]); // number
const primeraString = primero(["a", "b", "c"]); // string
// Clase genérica
class Pila<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
}
// Constraints (restricciones)
interface ConId {
id: number;
}
function buscarPorId<T extends ConId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id);
}
// Utility Types
type UsuarioSoloLectura = Readonly<Usuario>;
type UsuarioParcial = Partial<Usuario>;
type UsuarioSinDireccion = Omit<Usuario, "direccion">;
type SoloNombreEmail = Pick<Usuario, "nombre" | "email">;
Funciones Tipadas
// Función con tipos explícitos
function calcularDescuento(
precio: number,
porcentaje: number
): number {
return precio * (1 - porcentaje / 100);
}
// Arrow function tipada
const multiplicar = (a: number, b: number): number => a * b;
// Sobrecarga de funciones
function procesar(valor: string): string;
function procesar(valor: number): number;
function procesar(valor: string | number): string | number {
if (typeof valor === "string") {
return valor.toUpperCase();
}
return valor * 2;
}
// Type guards
function esString(valor: unknown): valor is string {
return typeof valor === "string";
}
function formatearValor(valor: unknown): string {
if (esString(valor)) {
return valor.trim();
}
return String(valor);
}
Clases con TypeScript
abstract class Entidad {
constructor(
public readonly id: string,
public creadoEn: Date = new Date()
) {}
abstract validar(): boolean;
}
class Producto extends Entidad {
constructor(
id: string,
public nombre: string,
public precio: number,
private _stock: number = 0
) {
super(id);
}
get stock(): number {
return this._stock;
}
set stock(valor: number) {
if (valor < 0) {
throw new Error("El stock no puede ser negativo");
}
this._stock = valor;
}
validar(): boolean {
return this.nombre.length > 0 && this.precio > 0;
}
aplicarDescuento(porcentaje: number): number {
return this.precio * (1 - porcentaje / 100);
}
}
// Implementando interfaces
interface Serializable {
toJSON(): string;
}
class Item implements Serializable {
constructor(public nombre: string) {}
toJSON(): string {
return JSON.stringify({ nombre: this.nombre });
}
}
Configuración del Proyecto
tsconfig.json Recomendado
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Lista de Verificación de Aprendizaje
- Dominar tipos primitivos y arrays
- Entender interfaces y type aliases
- Aprender generics y constraints
- Estudiar utility types (Partial, Readonly, Pick, Omit)
- Practicar type guards y narrowing
- Configurar proyectos con tsconfig.json
- Migrar un proyecto JavaScript existente
Errores Comunes a Evitar
Usar→ Usaanyen todos ladosunknowno tipos específicosIgnorar errores de compilación→ Corrige todos los errores de tipoNo usar strict mode→ Siempe activastrict: trueDuplicar tipos→ Usa utility types para derivar tipos
Recursos Esenciales
Cita
“TypeScript es JavaScript que escala.” - Anders Hejlsberg, creador de TypeScript
¡TypeScript transforma la manera en que escribes JavaScript. Invierte tiempo aprendiendo sus características y tu productividad aumentará significativamente!