TypeScript es un superset de JavaScript que añade tipos estáticos y otras características avanzadas. Se compila a JavaScript puro.
# Instalar TypeScript globalmente
npm install -g typescript
# Inicializar un proyecto
tsc --init # Crea tsconfig.json
# Compilar archivos TypeScript
tsc archivo.ts
# Modo observador (compilación automática)
tsc --watch
{
"compilerOptions": {
"target": "ES6", // Versión de JS a generar
"module": "commonjs", // Sistema de módulos
"strict": true, // Habilita todas las verificaciones de tipo
"outDir": "./dist", // Carpeta de salida
"rootDir": "./src", // Carpeta de origen
"esModuleInterop": true // Mejor interoperabilidad
},
"include": ["src/**/*"] // Archivos a incluir
}
let nombre: string = "Juan";
let edad: number = 30;
let esActivo: boolean = true;
// Arrays
let numeros: number[] = [1, 2, 3];
let frutas: Array<string> = ["manzana", "pera"];
// Tuplas (arreglos con tipos fijos)
let persona: [string, number] = ["Juan", 30];
// Any (evitar cuando sea posible)
let variableDinamica: any = "puede ser cualquier cosa";
variableDinamica = 42;
// Void (para funciones que no retornan valor)
function mostrarMensaje(): void {
console.log("Hola");
}
// Never (para funciones que nunca terminan)
function lanzarError(mensaje: string): never {
throw new Error(mensaje);
}
// Unión de tipos
let id: string | number = "ABC123";
id = 123;
// Alias de tipos
type ID = string | number;
let userId: ID = "USER123";
// Literal types
type Direccion = "norte" | "sur" | "este" | "oeste";
let direccion: Direccion = "norte";
interface Persona {
nombre: string;
edad: number;
direccion?: string; // Propiedad opcional
}
function saludar(persona: Persona): void {
console.log(`Hola ${persona.nombre}`);
}
const juan: Persona = {
nombre: "Juan",
edad: 30
};
interface Empleado extends Persona {
puesto: string;
salario: number;
}
const empleado: Empleado = {
nombre: "María",
edad: 28,
puesto: "Desarrolladora",
salario: 50000
};
extends
)// Función normal
function sumar(a: number, b: number): number {
return a + b;
}
// Función flecha
const multiplicar: (a: number, b: number) => number =
(a, b) => a * b;
// Parámetros opcionales
function crearUsuario(
nombre: string,
edad?: number // El '?' indica opcional
): void {
// ...
}
// Declaraciones de sobrecarga
function obtener(id: number): Usuario;
function obtener(email: string): Usuario;
// Implementación
function obtener(parametro: number | string): Usuario {
if (typeof parametro === "number") {
// Buscar por id
} else {
// Buscar por email
}
}
class Persona {
// Propiedades
nombre: string;
private edad: number;
protected id: string;
// Constructor
constructor(nombre: string, edad: number) {
this.nombre = nombre;
this.edad = edad;
this.id = Math.random().toString(36).substr(2, 9);
}
// Métodos
public saludar(): void {
console.log(`Hola, soy ${this.nombre}`);
}
}
public
: Accesible desde cualquier lugar (default)private
: Solo accesible dentro de la claseprotected
: Accesible dentro de la clase y subclasesreadonly
: Propiedad de solo lecturainterface SerVivo {
respirar(): void;
}
class Animal implements SerVivo {
respirar(): void {
console.log("Respirando...");
}
}
class Perro extends Animal {
constructor(private nombre: string) {
super();
}
ladrar(): void {
console.log("¡Guau!");
}
}
function identidad<T>(arg: T): T {
return arg;
}
let salida1 = identidad<string>("hola");
let salida2 = identidad(42); // Inferencia de tipo
interface RespuestaAPI<T> {
data: T;
status: number;
mensaje?: string;
}
const respuestaUsuario: RespuestaAPI<Usuario> = {
data: { id: 1, nombre: "Juan" },
status: 200
};
class Caja<T> {
private contenido: T;
constructor(contenido: T) {
this.contenido = contenido;
}
obtenerContenido(): T {
return this.contenido;
}
}
const cajaString = new Caja<string>("sorpresa");
const cajaNumero = new Caja(42); // Inferencia
interface Usuario {
id: number;
nombre: string;
email: string;
activo: boolean;
}
// Partial: hace todas las propiedades opcionales
type UsuarioParcial = Partial<Usuario>;
// Readonly: hace todas las propiedades readonly
type UsuarioSoloLectura = Readonly<Usuario>;
// Pick: selecciona propiedades específicas
type UsuarioBasico = Pick<Usuario, "id" | "nombre">;
// Omit: omite propiedades específicas
type UsuarioSinID = Omit<Usuario, "id">;
type TipoDeDato<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
"otro";
type T1 = TipoDeDato<string>; // "string"
type T2 = TipoDeDato<Date>; // "otro"
// Hacer todas las propiedades opcionales y de tipo string
type Stringify<T> = {
[P in keyof T]?: string;
};
type UsuarioStrings = Stringify<Usuario>;
/*
{
id?: string;
nombre?: string;
email?: string;
activo?: string;
}
*/
"experimentalDecorators": true
en tsconfig.json.
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class MiClase {
propiedad = "valor";
}
function log(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Llamando a ${propertyKey} con args:`, args);
const resultado = original.apply(this, args);
console.log(`Resultado:`, resultado);
return resultado;
};
return descriptor;
}
class Calculadora {
@log
sumar(a: number, b: number): number {
return a + b;
}
}
// tipos.d.ts
declare module "mi-modulo" {
export function funcion1(param: string): number;
export const constante1: string;
}
// Instalar tipos para librerías populares
npm install --save-dev @types/lodash @types/express
// Declaración rápida para módulos sin tipos
declare module "modulo-sin-tipos";
"allowJs": true
TypeScript ofrece un sistema de tipos poderoso que mejora la calidad y mantenibilidad del código JavaScript. Aunque tiene una curva de aprendizaje, los beneficios en proyectos medianos y grandes son significativos.