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