Módulo 1 — Fundamentos y Sintaxis de TypeScript
Aplicación práctica: Sistema de gestión de recursos sanitarios (Humanos y materiales)
1. Qué es ECMAScript
ECMAScript es el estándar que define el lenguaje JavaScript, desarrollado por Ecma International. TypeScript es un superset de JavaScript, lo que significa que todo código JavaScript válido también es válido en TypeScript, pero añade tipado estático, decoradores y otras capacidades avanzadas.
const nombre: string = 'Hospital Central';
console.log(`Bienvenido a la app de gestión de ${nombre}`);
2. Qué es TypeScript
TypeScript es un lenguaje de programación fuertemente tipado y transpilado. El código TypeScript se compila a JavaScript, permitiendo detectar errores en tiempo de desarrollo.
Ventajas clave:
- Tipado estático opcional
- Mejor autocompletado y refactorización
- Código más mantenible y escalable
let usuario: string = 'María';
console.log(`Hola ${usuario}, bienvenida al sistema de gestión.`);
let recursos: number = 10;
let total: number = recursos * 2;
console.log(`Total de recursos disponibles: ${total}`);
3. Impresión por consola
El objeto console funciona igual que en JavaScript, pero con mayor control gracias al tipado.
interface RecursoResumen {
tipo: string;
cantidad: number;
}
const recursos: RecursoResumen[] = [
{ tipo: 'Enfermeros', cantidad: 200 },
{ tipo: 'Ambulancias', cantidad: 40 },
];
console.log('Recursos actuales:');
console.info('Datos cargados correctamente.');
console.warn('Mascarillas por debajo del nivel recomendado.');
console.error('Error al conectar con la base de datos.');
console.table(recursos);
4. Declaración de variables y modificadores de acceso
En TypeScript se utilizan let y const (no se recomienda var). Además, las clases sí soportan modificadores de acceso explícitos:
-
public(por defecto) privateprotectedreadonly
type TipoRecurso = 'HUMANO' | 'MATERIAL';
class Recurso {
private id: string;
public unidad: string;
public tipoRecurso: TipoRecurso;
constructor(id: string, unidad: string, tipoRecurso: TipoRecurso) {
this.id = id;
this.unidad = unidad;
this.tipoRecurso = tipoRecurso;
}
public mostrar(): void {
console.log(`Recurso [id=${this.id}, tipo=${this.tipoRecurso}, unidad=${this.unidad}]`);
}
}
const recurso = new Recurso('2jfn49cn2s8ad8cn2a2f342da', 'JMAPER', 'HUMANO');
recurso.mostrar();
5. Tipos primitivos
TypeScript define explícitamente los tipos:
let id: string = '12ERC7DFJG94KGLS045JD7';
let cantidad: number = 32;
let activo: boolean = true;
let unidad: undefined = undefined;
let otrosDatos: null = null;
6. Operadores
Los operadores funcionan igual que en JavaScript, pero TypeScript evita combinaciones peligrosas mediante el tipado.
console.log(10 + 5);
console.log(10 / 3);
console.log(10 % 3);
let enfermeros: number = 10;
let ambulancias: number = 5;
console.log(enfermeros > 0 && ambulancias > 0);
console.log(!(enfermeros > 0));
console.log(10 === 10); // true
7. Arrays y genéricos
Los arrays en TypeScript suelen ser homogéneos y tipados:
interface RecursoInventario {
id: string;
unidad: string;
tipoRecurso: TipoRecurso;
}
const recursos: RecursoInventario[] = [
{ id: '18HFHSK2J3H123H412KH3', unidad: 'JMAPER', tipoRecurso: 'HUMANO' },
];
const ambulancias: string[] = ['ET 101467', 'ET 101468', 'ET 101469'];
ambulancias.push('ET 101470');
ambulancias.pop();
ambulancias.forEach(a => console.log(a));
8. Funciones
Las funciones definen tipos de parámetros y retorno.
function calcularAmbulanciasOperativas(total: number, inoperativas: number): number {
return total - inoperativas;
}
Parámetros por defecto
function registrarRecurso(
tipo: TipoRecurso = 'HUMANO',
id: string = '1AJS8DF9J4GJ80DJS2NSJD',
unidad: string = 'JMAPER'
): void {
console.log(`Recurso: ${tipo}, Unidad: ${unidad}`);
}
Funciones anidadas y ámbito
function gestionarRecurso(): void {
const tipo: TipoRecurso = 'MATERIAL';
function mostrarTipo(): void {
console.log(`Tipo de recurso: ${tipo}`);
}
mostrarTipo();
}
Funciones flecha
const reporteRecursos = (enfermeros: number, ambulancias: number): void => {
console.log(`Enfermeros: ${enfermeros}, Ambulancias: ${ambulancias}`);
};
9. Estructuras de control
let ambulanciasDisponibles: number = 12;
if (ambulanciasDisponibles > 0) {
console.log('Hay ambulancias');
} else {
console.log('No hay ambulancias disponibles');
}
try {
let resultado = ambulanciasDisponibles / 0;
console.log(resultado);
} catch (error) {
console.error('Error en el cálculo', error);
}
const listaAmbulancias: string[] = ['ET 101467', 'ET 101468', 'ET 101469'];
for (const amb of listaAmbulancias) {
console.log(`Ambulancia: ${amb}`);
}
10. Clases, interfaces y objetos
Interfaces
interface RecursoDTO {
id: string;
unidad: string;
tipoRecurso: TipoRecurso;
}
De las interfaces pueden crearse objetos literales, que son objetos definidos ad-hoc:
const recursoDTOEjemplo: RecursoDTO = {
id: "21j5jshsy34js8skasu",
unidad: "JMAPER",
tipoRecurso: "MATERIAL"
};
Clases
class RecursoEntidad {
constructor(
private id: string,
public unidad: string,
public tipoRecurso: TipoRecurso
) {}
mostrar(): void {
console.log(`Recurso [id=${this.id}, tipo=${this.tipoRecurso}, unidad=${this.unidad}]`);
}
}
const datos: RecursoDTO = {
id: '1j273hf83hd93j4f7gjd6',
unidad: 'ACING',
tipoRecurso: 'MATERIAL',
};
const recursoEntidad = new RecursoEntidad(datos.id, datos.unidad, datos.tipoRecurso);
recursoEntidad.mostrar();
10.1 Propiedades opcionales (?) y operador de aserción no nula (!)
En sistemas reales (como un sistema de gestión sanitaria), no todas las propiedades están siempre disponibles. TypeScript permite modelar esta realidad de forma segura.
Propiedades opcionales (?)
El operador ? indica que una propiedad puede existir o no. Internamente, TypeScript la trata como tipo | undefined.
interface RecursoDetalle {
id: string;
unidad: string;
tipoRecurso: TipoRecurso;
observaciones?: string; // propiedad opcional
}
Uso práctico:
const recursoConObs: RecursoDetalle = {
id: 'AJS829DJ2',
unidad: 'JMAPER',
tipoRecurso: 'MATERIAL',
observaciones: 'Revisión pendiente',
};
const recursoSinObs: RecursoDetalle = {
id: 'KSI928DJ2',
unidad: 'ACING',
tipoRecurso: 'HUMANO',
};
Al acceder a una propiedad opcional, TypeScript obliga a comprobar su existencia:
if (recursoConObs.observaciones) {
console.log(recursoConObs.observaciones.toUpperCase());
}
Esto evita errores típicos de JavaScript en tiempo de ejecución.
Operador de aserción no nula (!)
El operador ! se utiliza cuando el desarrollador sabe que una propiedad existe, aunque TypeScript no pueda deducirlo.
Es una forma de decirle al compilador: “Confía en mí, esta propiedad no es
nullniundefinedaquí.”
Ejemplo:
class RecursoAsignado {
public responsable?: string;
asignar(responsable: string): void {
this.responsable = responsable;
}
mostrarResponsable(): void {
// TypeScript advierte que responsable podría ser undefined
console.log(this.responsable!.toUpperCase());
}
}
Uso:
const recurso = new RecursoAsignado();
recurso.asignar('Dra. Martínez');
recurso.mostrarResponsable();
Aquí:
-
responsablees opcional (?) - El operador
!indica que en este punto concreto sí está definido
Buenas prácticas importantes
-
?modela incertidumbre real del dominio -
!debe usarse con criterio, solo cuando:- La lógica del programa garantiza la existencia
- Ya se ha validado previamente
-
Un abuso de
!puede ocultar errores reales
Ejemplo correcto:
if (recurso.responsable) {
console.log(recurso.responsable.toUpperCase());
}
Ejemplo a evitar sin validación previa:
console.log(recurso.responsable!.toUpperCase());
11. Otros objetos
Date
const fechaHoy: Date = new Date();
console.log('Fecha actual:', fechaHoy.toLocaleDateString());
const ultimaOperatividad: Date = new Date(2025, 9, 22);
console.log('Última fecha de operatividad:', ultimaOperatividad.toLocaleDateString());
Math
console.log('Número aleatorio:', Math.random());
console.log('Redondeo hacia arriba:', Math.ceil(4.3));
console.log('Valor absoluto:', Math.abs(-5));
console.log('Máximo:', Math.max(10, 20, 5));
type (Alias de tipos)
La palabra clave type permite crear alias de tipos, facilitando la reutilización y la legibilidad del código. Es especialmente útil para uniones, tipos compuestos y contratos simples.
type IDRecurso = string;
type UnidadSanitaria = string;
type Cantidad = number;
type EstadoRecurso = 'OPERATIVO' | 'INOPERATIVO' | 'EN_MANTENIMIENTO';
Uso práctico en el sistema:
type RecursoBasico = {
id: IDRecurso;
unidad: UnidadSanitaria;
estado: EstadoRecurso;
};
const recursoBasico: RecursoBasico = {
id: '7HG82JD92KS9',
unidad: 'JMAPER',
estado: 'OPERATIVO',
};
También pueden combinarse con interfaces:
type RecursoCompleto = RecursoDTO & {
estado: EstadoRecurso;
fechaAlta: Date;
};
enum (Enumeraciones)
Los enum permiten definir conjuntos cerrados de valores, mejorando la seguridad semántica frente a strings libres.
Enum numérico
enum NivelPrioridad {
BAJA = 1,
MEDIA,
ALTA,
CRITICA,
}
const prioridadRecurso: NivelPrioridad = NivelPrioridad.ALTA;
console.log('Nivel de prioridad:', prioridadRecurso);
Enum de strings (recomendado)
enum EstadoOperativo {
OPERATIVO = 'OPERATIVO',
INOPERATIVO = 'INOPERATIVO',
EN_MANTENIMIENTO = 'EN_MANTENIMIENTO',
}
Uso en una clase:
class RecursoEstado {
constructor(
public id: string,
public estado: EstadoOperativo
) {}
mostrarEstado(): void {
console.log(`Recurso ${this.id} está ${this.estado}`);
}
}
const recursoEstado = new RecursoEstado(
'AJD829DJ29',
EstadoOperativo.EN_MANTENIMIENTO
);
recursoEstado.mostrarEstado();
Object
const resumen = {
humanos: 120,
materiales: 340,
};
console.log(Object.keys(resumen));
console.log(Object.values(resumen));
console.log(Object.entries(resumen));
JSON
Muy habitual en comunicaciones con APIs REST.
const recursoJson = JSON.stringify(recursoBasico);
console.log('JSON:', recursoJson);
const recursoParseado = JSON.parse(recursoJson) as RecursoBasico;
console.log('Objeto:', recursoParseado);
Set (colecciones sin duplicados)
const unidades = new Set<string>();
unidades.add('JMAPER');
unidades.add('ACING');
unidades.add('JMAPER'); // no se duplica
console.log('Unidades sanitarias:', unidades);
Map (clave–valor tipado)
const inventario = new Map<string, number>();
inventario.set('Ambulancias', 40);
inventario.set('Enfermeros', 200);
console.log('Ambulancias:', inventario.get('Ambulancias'));