06 - TypeScript

TypeScript es un superconjunto tipado de JavaScript (tema 04): añade tipos estáticos que el compilador comprueba y que no existen en la ejecución. Se compila con tsc, y el JavaScript resultante es lo que ejecutan el navegador y Node. La instalación del proyecto con npm se explica en el tema 05.

npm install --save-dev typescript   # dependencia de desarrollo (tema 05)
npx tsc src/main.ts                 # compila un fichero suelto
npx tsc                             # compila según tsconfig.json
npx tsc --watch                     # recompila al guardar
node dist/main.js                   # ejecuta el resultado compilado

El tsconfig.json configura la compilación; npx tsc –init genera uno de partida:

{
  "compilerOptions": {
    "target": "es2022",
    "module": "es2022",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true
  }
}

Opción Función
target versión de JavaScript que genera el compilador
module sistema de módulos del resultado (import/export)
outDir / rootDir carpeta de salida (dist) y de origen (src)
strict exige disciplina de tipos; configuración recomendada

const id: number = 42;
const title: string = "Código limpio";
const available = true;                        // boolean: lo deduce el compilador
const tags: string[] = ["programming", "craft"];
const pair: [string, number] = ["total", 3];   // tupla: tipos por posición

function discount(price: number, percent: number): number {
  return price * (1 - percent / 100);
}

function announce(message: string): void {     // no devuelve nada
  console.log(message);
}

  • La anotación se escribe tras el nombre: id: number; void marca funciones sin retorno.
  • Cuando el valor es evidente, el compilador deduce el tipo sin anotarlo (available).
  • No hay conversión implícita: discount(“100”, 20) no compila.

Una interfaz describe la forma de los datos, no su comportamiento:

interface Book {
  id: number;
  title: string;
  available: boolean;
  authorId?: number;          // opcional: puede faltar
  readonly createdAt: Date;   // no modificable tras crearlo
}

const book: Book = {
  id: 1,
  title: "Código limpio",
  available: true,
  createdAt: new Date(),
};

  • ? marca la propiedad que puede faltar; el compilador obliga a contemplar su ausencia al usarla.
  • readonly impide modificar la propiedad desde el exterior tras crear el objeto.

Los tipos literales restringen un valor a opciones concretas:

type Genre = "novela" | "ensayo" | "teatro";
type OrderStatus = "PENDING" | "CONFIRMED" | "CANCELLED";

function canCancel(status: OrderStatus): boolean {
  return status === "PENDING";
}

canCancel("SENT");   // error de compilación: el literal no está en la unión

Una unión también puede mezclar tipos; en cada rama el compilador acota el tipo disponible:

function describe(value: string | number): string {
  if (typeof value === "string") return value;
  return `id ${value}`;        // aquí, value es number
}

let data: any = JSON.parse(text);         // evítalo: desactiva la comprobación
let payload: unknown = JSON.parse(text);  // admite cualquier valor,
                                          // pero exige comprobar el tipo antes de usarlo

if (typeof payload === "string") {
  console.log(payload.toUpperCase());     // ok: ya es string
}

any contagia la ausencia de tipos a todo lo que toca; unknown obliga a comprobar el tipo antes de operar. Se usa unknown cuando no se conoce el contenido y tipos concretos en cuanto se pueda.

interface ApiResponse<T> {
  data: T;
  status: number;
}

const response: ApiResponse<Book> = { data: book, status: 200 };

  • <T> es un parámetro de tipo que se fija en cada uso: ApiResponse<Book> tiene data de tipo Book.
  • Sirve para un mismo envoltorio con distintos contenidos; Array<string> es lo mismo que string[].

// src/price-calculator.ts
export class PriceCalculator {
  discount(price: number, percent: number): number {
    return price * (1 - percent / 100);
  }
}

// src/main.ts
import { PriceCalculator } from "./price-calculator.js";

const calculator = new PriceCalculator();
console.log(calculator.discount(100, 20)); // 80

  • La POO es la ya estudiada en Programación; TypeScript añade los tipos a campos, parámetros y retorno.
  • export publica y import consume; la extensión .js del import corresponde al archivo compilado de dist/.

interface BookResponse {
  id: number;
  title: string;
  authorName: string;
}

async function getBook(id: number): Promise<BookResponse> {
  const response = await fetch(`/api/books/${id}`);
  return response.json();
}

  • fetch y async/await se explican en el tema 07; el tipo describe el JSON que entregará la API.
  • Si la API cambia su JSON, el compilador avisa de todos los puntos del cliente que necesitan adaptarse.
Los tipos no existen en la ejecución: no viajan en el JSON ni validan lo que llega. Su valor está en detectar errores antes de ejecutar y en documentar la forma de los datos que viajan entre cliente y API.
  • clase/daw/lmsgi/2eval/typescript.txt
  • Última modificación: 2026/10/21 10:30
  • por cesguiro