TechLead
Lección 3 de 8
5 min de lectura
TypeScript

Interfaces y alias de tipos

Define tipos personalizados con interfaces y alias de tipos, y aprende cuándo usar cada uno

Alias de tipos

Los alias de tipos crean un nuevo nombre para un tipo:

// Alias de tipo simple
type ID = string | number;
type Username = string;

// Alias de tipo para objeto
type User = {
  id: ID;
  name: string;
  email: string;
  age?: number;  // opcional
};

// Alias de tipo para función
type Greeting = (name: string) => string;

// Alias de tipo unión
type Status = "pending" | "active" | "completed";

// Usando alias de tipos
let userId: ID = "abc123";
let user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com"
};

const greet: Greeting = (name) => `Hello, ${name}!`;

Interfaces

Las interfaces definen la forma de los objetos:

// Interface básica
interface User {
  id: number;
  name: string;
  email: string;
  age?: number;           // propiedad opcional
  readonly createdAt: Date;  // propiedad readonly
}

// Usando la interface
const user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  createdAt: new Date()
};

// Interface de función
interface SearchFunc {
  (query: string, limit?: number): string[];
}

const search: SearchFunc = (query, limit = 10) => {
  return ["result1", "result2"];
};

// Firma de índice
interface StringDictionary {
  [key: string]: string;
}

const dict: StringDictionary = {
  hello: "world",
  foo: "bar"
};

Extender interfaces

// Interface base
interface Animal {
  name: string;
  age: number;
}

// Extender una sola interface
interface Dog extends Animal {
  breed: string;
  bark(): void;
}

const dog: Dog = {
  name: "Max",
  age: 3,
  breed: "Labrador",
  bark() {
    console.log("Woof!");
  }
};

// Extender múltiples interfaces
interface Timestamps {
  createdAt: Date;
  updatedAt: Date;
}

interface Post extends Animal, Timestamps {
  title: string;
  content: string;
}

// Extender con override (debe ser compatible)
interface SpecialAnimal extends Animal {
  age: 1 | 2 | 3;  // tipo más específico es válido
}

Tipos de intersección

// Los alias de tipos pueden usar intersecciones
type Animal = {
  name: string;
  age: number;
};

type CanFly = {
  fly(): void;
  wingspan: number;
};

// Combinar tipos con &
type Bird = Animal & CanFly;

const eagle: Bird = {
  name: "Eagle",
  age: 5,
  wingspan: 2.3,
  fly() {
    console.log("Flying!");
  }
};

// Intersección con interfaces también
interface Person {
  name: string;
}

interface Employee {
  employeeId: number;
  department: string;
}

type Staff = Person & Employee;

const staff: Staff = {
  name: "Alice",
  employeeId: 123,
  department: "Engineering"
};

Fusión de declaraciones de interfaces

Las interfaces pueden declararse varias veces y se fusionan:

// Primera declaración
interface Config {
  apiUrl: string;
}

// Segunda declaración (se fusiona con la primera)
interface Config {
  timeout: number;
}

// Resultado: Config tiene ambas propiedades
const config: Config = {
  apiUrl: "https://api.example.com",
  timeout: 5000
};

// Útil para extender tipos de librerías
interface Window {
  myCustomProperty: string;
}

// Ahora window.myCustomProperty está tipado

Alias de tipos vs interfaces

// Ambos pueden definir formas de objetos
type UserType = {
  name: string;
  age: number;
};

interface UserInterface {
  name: string;
  age: number;
}

// Los alias pueden definir primitivos, uniones, tuplas
type ID = string | number;           // No se puede con interface
type Coordinates = [number, number]; // No se puede con interface
type Status = "active" | "inactive"; // No se puede con interface

// Las interfaces pueden extenderse y fusionarse
interface Animal {
  name: string;
}
interface Dog extends Animal {
  breed: string;
}

// Los tipos usan intersección para composición
type Animal2 = { name: string };
type Dog2 = Animal2 & { breed: string };

// Las interfaces soportan fusión de declaraciones
interface User { name: string; }
interface User { age: number; }  // Se fusiona

// Los alias de tipo no pueden fusionarse
// type User = { name: string };
// type User = { age: number };  // Error: identificador duplicado

Cuándo usar cada uno

Usa interfaces cuando:

  • • Definas formas de objetos
  • • Crees contratos para clases
  • • Necesites fusión de declaraciones
  • • Trabajes con librerías/APIs

Usa alias de tipos cuando:

  • • Definas tipos unión
  • • Definas tipos de tuplas
  • • Crees utilidades de tipos
  • • Alias de tipos primitivos

Ejemplos prácticos

// Tipado de respuesta de API
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

interface User {
  id: number;
  name: string;
  email: string;
}

type UserResponse = ApiResponse<User>;
type UsersResponse = ApiResponse<User[]>;

// Props de componente
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary" | "danger";
  disabled?: boolean;
}

// Datos de formulario
interface LoginForm {
  username: string;
  password: string;
  rememberMe?: boolean;
}

// Manejadores de eventos
type ClickHandler = (event: MouseEvent) => void;
type ChangeHandler = (value: string) => void;

Puntos clave

  • • Los alias de tipos crean nuevos nombres para tipos
  • • Las interfaces definen contratos para objetos
  • • Las interfaces pueden extender otras interfaces
  • • Los alias usan & para intersecciones
  • • Las interfaces soportan fusión de declaraciones
  • • Usa interfaces para objetos, tipos para uniones/primitivos

Continuar Aprendiendo