Type aliases y aserciones de tipo

Básico
TypeScript
TypeScript
Actualizado: 18/04/2026

Alias de tipos con type

Los alias de tipos permiten asignar un nombre personalizado a cualquier tipo de TypeScript. La palabra clave type crea un alias que funciona exactamente como el tipo original, pero con un nombre descriptivo que mejora la legibilidad y facilita la reutilización.

Composición de tipos con type aliases

type Identificador = string;
type Cantidad = number;
type Activo = boolean;

const userId: Identificador = "usr_7890";
const stock: Cantidad = 150;
const enServicio: Activo = true;

console.log(userId, stock, enServicio);

Los alias para tipos primitivos tienen utilidad limitada, pero la sintaxis es la misma que para tipos más complejos.

Alias para objetos

El uso más habitual de type es definir la estructura de objetos que se reutilizan en múltiples puntos del código:

type Usuario = {
  id: string;
  nombre: string;
  edad: number;
  activo: boolean;
};

const nuevoUsuario: Usuario = {
  id: "usr_001",
  nombre: "Ana Garcia",
  edad: 30,
  activo: true
};

function mostrarUsuario(usuario: Usuario): void {
  console.log(`${usuario.nombre} (ID: ${usuario.id}), ${usuario.edad} anos`);
}

mostrarUsuario(nuevoUsuario);

Si se intenta crear un objeto que no cumple con la estructura definida, TypeScript señala el error:

// Error: Property 'edad' is missing in type '{ id: string; nombre: string; }'
// const incompleto: Usuario = { id: "usr_002", nombre: "Carlos" };

Alias para uniones de tipos

Los alias son especialmente útiles para definir union types con nombres descriptivos:

type Estado = "pendiente" | "procesando" | "completado" | "fallido";
type CodigoRespuesta = 200 | 201 | 400 | 404 | 500;
type Resultado = string | number;

function actualizarEstado(pedidoId: string, estado: Estado): void {
  console.log(`Pedido ${pedidoId}: ${estado}`);
}

actualizarEstado("ped_001", "completado");
// actualizarEstado("ped_002", "cancelado"); // Error: '"cancelado"' is not assignable to type 'Estado'

Alias para funciones

Los alias pueden describir la firma de una función, incluyendo los tipos de sus parámetros y su valor de retorno:

type Comparador = (a: number, b: number) => number;
type Validador = (valor: string) => boolean;
type Callback = (error: Error | null, resultado: string) => void;

const ordenarAsc: Comparador = (a, b) => a - b;
const ordenarDesc: Comparador = (a, b) => b - a;

const esEmailValido: Validador = (valor) => valor.includes("@");

const números = [5, 3, 8, 1, 9, 2];
console.log(números.slice().sort(ordenarAsc));
console.log(números.slice().sort(ordenarDesc));
console.log(esEmailValido("usuario@ejemplo.com"));

Los alias de función son útiles para tipar callbacks y estrategias que se pasan como parámetros:

type Transformacion = (texto: string) => string;

function aplicarTransformaciones(texto: string, transformaciones: Transformacion[]): string {
  return transformaciones.reduce((resultado, fn) => fn(resultado), texto);
}

const resultado = aplicarTransformaciones("  Hola Mundo  ", [
  (t) => t.trim(),
  (t) => t.toLowerCase(),
  (t) => t.replace(" ", "_")
]);

console.log(resultado); // "hola_mundo"

Alias con propiedades opcionales

Las propiedades opcionales se marcan con ? y pueden estar ausentes en los objetos que cumplen el tipo:

type Configuración = {
  host: string;
  puerto: number;
  ssl?: boolean;
  timeout?: number;
};

const configMinima: Configuración = {
  host: "localhost",
  puerto: 3000
};

const configCompleta: Configuración = {
  host: "api.ejemplo.com",
  puerto: 443,
  ssl: true,
  timeout: 5000
};

console.log(configMinima, configCompleta);

Composición de tipos

Los alias se pueden combinar para crear tipos más complejos a partir de tipos existentes:

type Direccion = {
  calle: string;
  ciudad: string;
  codigoPostal: string;
};

type Contacto = {
  email: string;
  telefono?: string;
};

type Cliente = {
  id: string;
  nombre: string;
  dirección: Direccion;
  contacto: Contacto;
};

const cliente: Cliente = {
  id: "cli_001",
  nombre: "Elena Torres",
  dirección: {
    calle: "Gran Via 42",
    ciudad: "Madrid",
    codigoPostal: "28013"
  },
  contacto: {
    email: "elena@ejemplo.com",
    telefono: "+34 600 123 456"
  }
};

console.log(cliente.nombre, cliente.contacto.email);

type frente a interface

Tanto type como interface permiten definir la forma de un objeto, pero tienen diferencias importantes:

// Con type alias
type PuntoType = {
  x: number;
  y: number;
};

// Con interface
interface PuntoInterface {
  x: number;
  y: number;
}

Diferencias clave

Las interfaces permiten la extensión y el declaration merging (fusionar declaraciones con el mismo nombre):

interface Animal {
  nombre: string;
}

interface Animal {
  edad: number;
}

// TypeScript fusiona ambas declaraciones
const gato: Animal = { nombre: "Luna", edad: 3 };
console.log(gato);
// Las interfaces se extienden con extends
interface Mascota extends Animal {
  propietario: string;
}

const perro: Mascota = { nombre: "Rex", edad: 5, propietario: "Carlos" };
console.log(perro);

Los type aliases no se pueden reabrir ni fusionar, pero pueden representar tipos que las interfaces no pueden:

// Tipos que solo type puede representar
type ID = string | number;                    // Union
type Coordenadas = [number, number];          // Tupla
type Callback = () => void;                   // Función
type Literal = "activo" | "inactivo";         // Union de literales

console.log("ID, Coordenadas, Callback, Literal son tipos válidos");

Los type aliases extienden otros tipos mediante intersecciones:

type Base = {
  id: string;
  creado: Date;
};

type ConNombre = Base & {
  nombre: string;
};

const entidad: ConNombre = {
  id: "ent_001",
  creado: new Date(),
  nombre: "Ejemplo"
};

console.log(entidad);

La recomendación práctica es usar interface cuando se define la forma de un objeto que puede ser extendido, y type para uniones, tuplas, funciones y tipos compuestos.

Aserciones de tipo con as

Una aserción de tipo indica al compilador que trate un valor como un tipo más específico. No realiza ninguna conversión en tiempo de ejecución; es una directiva que solo afecta a la verificación de tipos durante la compilación.

let valor: unknown = "texto de ejemplo";

// Sin aserción, TypeScript no permite operaciones de string
// console.log(valor.toUpperCase()); // Error: 'valor' is of type 'unknown'

// Con aserción, TypeScript trata 'valor' como string
const texto = valor as string;
console.log(texto.toUpperCase());

Uso con el DOM

Las aserciones son habituales al trabajar con el DOM, donde TypeScript infiere tipos genéricos:

// TypeScript infiere que el resultado es Element | null
const boton = document.getElementById("mi-boton") as HTMLButtonElement | null;

if (boton !== null) {
  boton.disabled = true; // Acceso seguro a propiedades de HTMLButtonElement
  boton.textContent = "Deshabilitado";
}

const input = document.querySelector("input.email") as HTMLInputElement | null;

if (input !== null) {
  console.log(input.value); // Acceso a .value, específico de HTMLInputElement
}

Uso con datos externos

Al recibir datos de una API u otra fuente externa, las aserciones permiten tipar el resultado:

type Producto = {
  id: number;
  nombre: string;
  precio: number;
};

async function obtenerProducto(id: number): Promise<Producto> {
  const respuesta = await fetch(`/api/productos/${id}`);
  const datos = await respuesta.json() as Producto;
  return datos;
}

Precauciones con las aserciones

Las aserciones no realizan comprobaciones en tiempo de ejecución. Si el tipo real no coincide con la aserción, el programa fallara al ejecutarse:

const número = 42;
// TypeScript no permite aserciones directas entre tipos incompatibles
// const texto = número as string; // Error

// Se puede forzar con una doble aserción a través de unknown
const forzado = número as unknown as string;
// forzado.toUpperCase(); // Compila, pero falla en ejecución
console.log(typeof forzado); // "number", no "string"

Las aserciones deben usarse solo cuando se tiene certeza del tipo real del valor. Siempre que sea posible, es preferible utilizar guardas de tipo (typeof, instanceof) que realizan comprobaciones en tiempo de ejecución.

Aserción no nula

El operador ! después de una expresión es una aserción de no nulidad. Indica al compilador que el valor no es null ni undefined, eliminando esos tipos de la inferencia:

function obtenerElemento(id: string): HTMLElement {
  const elemento = document.getElementById(id);
  // elemento es HTMLElement | null
  // El operador ! asegura que no es null
  return elemento!;
}
type Mapa = {
  [clave: string]: string | undefined;
};

const traducciones: Mapa = {
  hola: "hello",
  adios: "goodbye"
};

// Sin !: tipo es string | undefined
// Con !: tipo es string
const traduccion = traducciones["hola"]!;
console.log(traduccion.toUpperCase());

La aserción no nula es una forma concisa de eliminar null y undefined del tipo, pero comparte la misma precaución que las aserciones regulares: si el valor resulta ser null en tiempo de ejecución, el programa fallara. Siempre que sea posible, es preferible una comprobación explícita con if:

const elemento = document.getElementById("contenedor");

// Preferible: comprobacion explícita
if (elemento !== null) {
  elemento.textContent = "Cargado";
}

// Alternativa: aserción no nula (solo cuando hay certeza)
// elemento!.textContent = "Cargado";

El operador satisfies

El operador satisfies válida que un valor cumple con un tipo determinado sin perder la inferencia del tipo literal. A diferencia de una anotación de tipo, que amplia el tipo al declarado, satisfies conserva la información precisa del valor:

type Colores = Record<string, [number, number, number] | string>;

// Con anotación de tipo: TypeScript solo conoce que los valores son [number, number, number] | string
const coloresAnotados: Colores = {
  rojo: [255, 0, 0],
  verde: "#00ff00",
  azul: [0, 0, 255]
};
// coloresAnotados.verde.toUpperCase(); // Error: Property 'toUpperCase' does not exist

// Con satisfies: TypeScript conserva el tipo literal de cada propiedad
const coloresSatisfies = {
  rojo: [255, 0, 0],
  verde: "#00ff00",
  azul: [0, 0, 255]
} satisfies Colores;

// TypeScript sabe que 'verde' es string y 'rojo' es una tupla
console.log(coloresSatisfies.verde.toUpperCase()); // Valido
console.log(coloresSatisfies.rojo[0]);             // Valido, tipo number

Uso práctico de satisfies

El operador satisfies es útil cuando se quiere validar la estructura de un objeto sin perder la precisión de los tipos individuales:

type Rutas = Record<string, string>;

const apiEndpoints = {
  usuarios: "/api/usuarios",
  productos: "/api/productos",
  pedidos: "/api/pedidos"
} satisfies Rutas;

// TypeScript conoce las claves exactas del objeto
console.log(apiEndpoints.usuarios);   // Valido
// console.log(apiEndpoints.categorias); // Error: Property 'categorias' does not exist
type ConfiguracionTema = {
  primario: string;
  secundario: string;
  fondo: string;
};

const temaOscuro = {
  primario: "#bb86fc",
  secundario: "#03dac6",
  fondo: "#121212"
} satisfies ConfiguracionTema;

// TypeScript sabe que cada valor es un literal de string, no solo string
console.log(temaOscuro.primario); // tipo: "#bb86fc"

La diferencia clave entre satisfies y una anotación de tipo es que satisfies válida y conserva, mientras que la anotación válida y amplia. Esto permite obtener la seguridad de la validación de tipos sin sacrificar la precisión de la inferencia.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, TypeScript es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de TypeScript

Explora más contenido relacionado con TypeScript y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Crear alias de tipos para primitivos, objetos, uniones y funciones con la palabra clave type. Aplicar aserciones de tipo con as para indicar al compilador un tipo más específico. Utilizar el operador de aserción no nula (!) para eliminar null y undefined del tipo. Comprender la diferencia entre type e interface para definir la forma de objetos. Conocer el operador satisfies para validar tipos sin ampliar la inferencia.