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

// 🚀 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

// 🚀 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

// 🚀 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 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

// 🚀 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

// 🚀 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

// 🚀 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

// 🚀 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)

// 🚀 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

// 🚀 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

// 🚀 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

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "rootDir": "src",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  }
}

Buenas prácticas

  • Usa unknown en lugar de any
  • Evita castings innecesarios (as)
  • Declara tipos con type y estructuras con interface
  • Usa strictNullChecks activado
  • Separa tipos y lógica en carpetas types/ o interfaces/
  • Aprovecha enum o as const para constantes
  • Prefiere inferencia de tipos (TypeScript es muy bueno en esto)


Usamos cookies para mejorar tu experiencia. ¿Aceptas las cookies de análisis?