Cheat Sheet completa de TypeScript
Esta cheat sheet de TypeScript es una referencia rápida y práctica para entender sus tipos, inferencias, interfaces, genéricos y funcionalidades modernas.
Ideal para pasar de JavaScript a TypeScript de forma fluida.
Tipos básicos
Los tipos básicos son la base de TypeScript y te permiten describir con claridad qué clase de dato espera cada variable.
// 🚀 TIPOS BÁSICOS
// Inferencia automática
let nombre = 'Carlos'; // string
let edad = 42; // number
let activo = true; // boolean
// Tipado explícito
let ciudad: string = 'Zaragoza';
let puntuacion: number = 98.5;
let registrado: boolean = false;
// Null y undefined
let nada: null = null;
let indefinido: undefined = undefined;
// Arrays
let numeros: number[] = [1, 2, 3];
let frutas: Array<string> = ['manzana', 'pera'];
// Tuplas
let usuario: [string, number] = ['Carlos', 42];
// Any (⚠️ evitarlo)
let variable: any = 123;
variable = 'ahora soy texto';
// Unknown (más seguro que any)
let valor: unknown = 'texto';
if (typeof valor === 'string') {
console.log(valor.toUpperCase());
}
// Never (para errores o funciones que no devuelven)
function error(mensaje: string): never {
throw new Error(mensaje);
}
// Void (sin retorno)
function saludar(): void {
console.log('Hola mundo');
}
Tipos avanzados
Los tipos avanzados amplían el modelado de datos con uniones, aliases, literales e intersecciones.
// 🚀 TIPOS AVANZADOS
// Union types
let id: number | string;
id = 123;
id = 'ABC';
// Type alias
type ID = number | string;
let usuarioID: ID = 42;
// Literal types
let rol: 'admin' | 'user' | 'guest';
rol = 'admin';
// Optional & default
function saluda(nombre: string, edad?: number): void {
console.log(`Hola ${nombre} ${edad ?? ''}`);
}
// Intersection types
type Persona = { nombre: string };
type Trabajador = { empresa: string };
type Empleado = Persona & Trabajador;
const empleado: Empleado = { nombre: 'Ana', empresa: 'TechCorp' };
// Enum
enum Estado {
Activo,
Inactivo,
Pendiente,
}
let estadoActual: Estado = Estado.Activo;
// Enum con valores personalizados
enum Rol {
Admin = 'ADMIN',
Editor = 'EDITOR',
User = 'USER',
}
Funciones
TypeScript tipa parámetros, retornos y firmas de función para que el comportamiento quede claro desde el principio.
// 🚀 FUNCIONES EN TYPESCRIPT
// Tipado de parámetros y retorno
function sumar(a: number, b: number): number {
return a + b;
}
// Arrow function
const multiplicar = (a: number, b: number): number => a * b;
// Parámetros opcionales
function log(mensaje: string, usuario?: string) {
console.log(usuario ? `${usuario}: ${mensaje}` : mensaje);
}
// Parámetros por defecto
function saluda2(nombre: string = 'desconocido') {
console.log(`Hola ${nombre}`);
}
// Rest parameters
function total(...numeros: number[]): number {
return numeros.reduce((acc, n) => acc + n, 0);
}
// Tipado de funciones
type Operacion = (a: number, b: number) => number;
const restar: Operacion = (a, b) => a - b;
Objetos, interfaces y tipos
Interfaces y type aliases sirven para definir estructuras reutilizables y mantener consistencia entre objetos.
// 🚀 INTERFACES Y TYPE ALIAS
// Interface
interface Usuario {
id: number;
nombre: string;
email?: string; // opcional
}
const u1: Usuario = { id: 1, nombre: 'Carlos' };
// Herencia de interfaces
interface Admin extends Usuario {
permisos: string[];
}
const admin: Admin = { id: 2, nombre: 'Sara', permisos: ['read', 'write'] };
// Type alias vs interface
type Producto = {
nombre: string;
precio: number;
};
// Index signature
interface Diccionario {
[clave: string]: string;
}
const traducciones: Diccionario = {
hola: 'hello',
adios: 'bye',
};
Clases
Las clases en TypeScript añaden tipado, modificadores de acceso y una herencia más explícita sobre JavaScript.
// 🚀 CLASES
class Persona {
// Propiedades con modificadores
public nombre: string;
protected edad: number;
private dni: string;
constructor(nombre: string, edad: number, dni: string) {
this.nombre = nombre;
this.edad = edad;
this.dni = dni;
}
saludar(): void {
console.log(`Hola, soy ${this.nombre}`);
}
}
const p1 = new Persona('Carlos', 43, '12345678A');
// Herencia
class Empleado extends Persona {
private puesto: string;
constructor(nombre: string, edad: number, dni: string, puesto: string) {
super(nombre, edad, dni);
this.puesto = puesto;
}
trabajar(): void {
console.log(`${this.nombre} trabaja como ${this.puesto}`);
}
}
// Propiedades de solo lectura y estáticas
class Config {
readonly version = '1.0.0';
static autor = 'TypeScript';
}
Genéricos
Los genéricos permiten reutilizar funciones, tipos o interfaces sin perder precisión en el tipado.
// 🚀 GENÉRICOS
// Función genérica
function identidad<T>(valor: T): T {
return valor;
}
const texto = identidad('Hola');
const numero = identidad(123);
// Genérico con restricción
function getPropiedad<T, K extends keyof T>(obj: T, clave: K): T[K] {
return obj[clave];
}
const persona = { nombre: 'Carlos', edad: 43 };
const edad = getPropiedad(persona, 'edad');
// Interfaces genéricas
interface Caja<T> {
contenido: T;
}
const cajaDeTexto: Caja<string> = { contenido: 'Hola' };
const cajaDeNumero: Caja<number> = { contenido: 99 };
Módulos e imports
Los módulos organizan el código en archivos reutilizables y facilitan importar solo lo que cada parte necesita.
// 🚀 MÓDULOS
// archivo utils.ts
export function sumar(a: number, b: number): number {
return a + b;
}
export const PI = 3.1416;
// archivo main.ts
import { sumar, PI } from './utils';
console.log(sumar(2, 3), PI);
// Export default
export default function saluda(nombre: string) {
console.log(`Hola ${nombre}`);
}
// Import default
import saluda from './utils';
Utility Types
Los utility types resuelven transformaciones muy comunes sobre tipos sin tener que reescribir estructuras enteras.
// 🚀 UTILITY TYPES MÁS ÚTILES
interface Usuario {
id: number;
nombre: string;
email?: string;
activo: boolean;
}
// Partial → convierte todas las props en opcionales
type UsuarioEditable = Partial<Usuario>;
// Required → todas las props obligatorias
type UsuarioCompleto = Required<Usuario>;
// Pick → selecciona propiedades específicas
type UsuarioMini = Pick<Usuario, 'id' | 'nombre'>;
// Omit → excluye propiedades
type UsuarioSinEmail = Omit<Usuario, 'email'>;
// Readonly → propiedades inmutables
type UsuarioSoloLectura = Readonly<Usuario>;
// Record → crea un mapa de claves y valores
type DiccionarioUsuarios = Record<string, Usuario>;
// ReturnType → obtiene el tipo de retorno de una función
type Resultado = ReturnType<typeof sumar>;
Narrowing (control de tipos)
El narrowing reduce un tipo amplio a otro más concreto según comprobaciones reales del código.
// 🚀 TYPE NARROWING
function procesar(valor: string | number) {
if (typeof valor === 'string') {
return valor.toUpperCase();
}
return valor * 2;
}
// instanceof
class Perro {
ladra() {}
}
class Gato {
maulla() {}
}
function hablar(animal: Perro | Gato) {
if (animal instanceof Perro) {
animal.ladra();
} else {
animal.maulla();
}
}
// in
interface Carro {
ruedas: number;
}
interface Barco {
anclas: number;
}
function mover(vehiculo: Carro | Barco) {
if ('ruedas' in vehiculo) {
console.log('Es un carro');
} else {
console.log('Es un barco');
}
}
Type Assertions y as const
Las assertions sirven para guiar al compilador, y as const fija valores para inferir tipos más precisos.
// 🚀 TYPE ASSERTIONS
// Forzar tipo
const valor = document.getElementById('input') as HTMLInputElement;
valor.value = 'Hola';
// Non-null assertion (!)
const btn = document.querySelector('button')!;
btn.disabled = true;
// const assertions
const COLORES = {
primario: '#ff99a7',
secundario: '#ffe8b9',
} as const;
// Literal types inferidos
type Colores = (typeof COLORES)[keyof typeof COLORES];
Tipos condicionales e inferencia
Los tipos condicionales permiten construir lógica de tipos y reutilizar patrones más avanzados a nivel estático.
// 🚀 TIPOS CONDICIONALES
type EsString<T> = T extends string ? 'es string' : 'no es string';
type A = EsString<string>; // "es string"
type B = EsString<number>; // "no es string"
// Inferencia en tipos
type Retorno<T> = T extends (...args: any[]) => infer R ? R : never;
type R1 = Retorno<() => number>; // number
type R2 = Retorno<() => string>; // string
Configuración básica tsconfig.json
tsconfig.json define cómo compila TypeScript y qué nivel de seguridad o compatibilidad quieres en el proyecto.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"rootDir": "src",
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}
Buenas prácticas
Estas prácticas ayudan a sacar partido a TypeScript sin convertir el código en algo más rígido de la cuenta.
- Usa
unknownen lugar deany - Evita castings innecesarios (
as) - Declara tipos con
typey estructuras coninterface - Usa
strictNullChecksactivado - Separa tipos y lógica en carpetas
types/ointerfaces/ - Aprovecha
enumoas constpara constantes - Prefiere inferencia de tipos (TypeScript es muy bueno en esto)