Skip to content

📕 Clase 4 — Métodos (Funciones)

TypeScript · 2026-07-11 · Carpeta: 02-Ejercicios/Metodos ⬅️ Volver al índice de clases

🎯 Qué aprendí

  • Cómo declarar funciones con parámetros tipados y tipo de retorno.
  • Funciones que no devuelven nada (: void) vs las que devuelven un valor.
  • Parámetros opcionales con ?.
  • La diferencia entre ? (opcional) y ! (que NO es un marcador de parámetro).
  • Parámetros rest (...) para recibir cantidad ilimitada + reduce.
  • Parámetros por defecto (= "Adiós") y arrow functions.
  • Sobrecarga de funciones: varias firmas, una sola implementación.

📖 PARTE TEÓRICA

🧩 1. Anatomía de una función

typescript
function sumar(numero1: number, numero2: number): number {
//       └nombre  └─── parámetros con tipo ───┘  └─ tipo que devuelve
  return numero1 + numero2;
}

Cada parte:

ParteEjemploQué es
NombresumarCómo llamas a la función
Parámetros(numero1: number, numero2: number)Datos de entrada, cada uno con su tipo
Tipo de retorno: numberQué tipo de valor devuelve
Cuerpo{ return ... }Lo que hace

💡 Tipar los parámetros hace que TS avise si los llamas mal: sumar(5, "10") → ❌ error, "10" no es number.

🕳️ 2. void (no devuelve) vs devolver un valor

typescript
// void: SOLO hace algo (imprime), no devuelve nada
function imprimeMensaje(mensaje: string): void {
  console.log(`Mensaje: ${mensaje}`);
}

// devuelve un number: se puede usar el resultado
function sumar(a: number, b: number): number {
  return a + b;
}
console.log(`Resultado: ${sumar(5, 10)}`);   // Resultado: 15
voidDevuelve un valor
Lleva return valor❌ No✅ Sí
Se puede usar el resultado❌ No (es undefined)✅ Sí
EjemploimprimeMensaje()sumar()

🧪 Entrevista: ¿Qué retorna una función void? Técnicamente undefined. Se usa cuando la función hace una acción (imprimir, guardar) pero no produce un valor para reutilizar.

❓ 3. Parámetros opcionales con ?

Un ? después del nombre del parámetro lo hace opcional: se puede omitir al llamar.

typescript
function saludar(nombre: string, saludo?: string): string {
  if (saludo) {
    return `${saludo}, ${nombre}!`;   // si me pasan saludo
  } else {
    return `Hola, ${nombre}!`;        // si no, uno por defecto
  }
}

console.log(saludar("Styp"));                 // Hola, Styp!
console.log(saludar("Styp", "Buenos días"));  // Buenos días, Styp!

💡 Un parámetro opcional (saludo?) en realidad es de tipo string | undefined: si no lo pasas, vale undefined. Por eso el if (saludo) comprueba si llegó.

⚠️ Los parámetros opcionales van al final. function f(a?: string, b: number) da error: uno obligatorio no puede ir después de uno opcional.

🚫 4. ? vs ! (corrección importante)

En clase quedó la idea de que ! marca un parámetro como "obligatorio". No es así.

typescript
function saludar(nombre: string) { }   // 'nombre' YA es obligatorio (sin marcador)
saludar();   // ❌ Error: Expected 1 arguments, but got 0
SímboloQué es de verdad
(nada)Un parámetro ya es obligatorio por defecto. No necesita marcador.
?Hace el parámetro opcional (nombre?: string).
!NO es un marcador de parámetro. function f(x!: string) es error de sintaxis.

📝 Corrección al apunte del profe: ! es el operador de non-null assertion, y se usa sobre un valor, no en un parámetro. Significa "confía en mí, esto no es null/undefined":

typescript
function longitud(texto: string | undefined): number {
  return texto!.length;   // ! le dice a TS que texto no es undefined
}

Resumen: por defecto = obligatorio, ? = opcional, ! = "no es null" (en valores).

🔢 5. Parámetros rest (...) — cantidad ilimitada

Con ... antes del parámetro puedes recibir cuántos argumentos quieras: TS los junta todos en un array. Se llaman rest parameters.

typescript
function sumarTodos(...numeros: number[]): number {
  //                └── rest: junta TODOS los argumentos en un number[]
  return numeros.reduce((acumulador, numero) => acumulador + numero, 0);
}

console.log(sumarTodos(1, 2, 3, 4, 5));   // 15
console.log(sumarTodos(10, 20));          // 30
console.log(sumarTodos());                // 0  (sin argumentos → array vacío)

Dentro de la función, numeros es un number[] normal. Aquí se recorre con reduce, que "acumula" todos los elementos en un solo valor:

typescript
numeros.reduce((acumulador, numero) => acumulador + numero, 0);
//              └── se arrastra la suma ──┘   └ cada elem   └ valor inicial (0)
Vueltaacumuladornumeroresultado
inicio00
1011
2123
3336
15

💡 ... (rest) debe ir al final de los parámetros (es "todo lo que sobre"). No confundir con el mismo ... usado para expandir un array (spread) — es la operación inversa.

🧪 Entrevista: ¿Diferencia entre rest y spread? Se escriben igual (...) pero: restjunta varios argumentos en un array (en la definición de la función); spread expande un array en valores sueltos (al llamar/copiar). Rest recoge, spread reparte.

⭐ 6. Parámetros por defecto y arrow functions

typescript
// Parámetro por defecto: si no lo pasas, usa el valor dado
function despedida(nombre: string, despedida: string = "Adiós"): string {
  return `${despedida}, ${nombre}!`;
}
despedida("Styp");                  // Adiós, Styp!
despedida("Styp", "Hasta mañana");  // Hasta mañana, Styp!

// Arrow function: forma corta de escribir funciones
const sumar = (a: number, b: number): number => a + b;
sumar(3, 7);   // 10

💡 despedida: string = "Adiós" (por defecto) es una alternativa más limpia al if/else con saludo? cuando siempre quieres un valor de respaldo: si falta el argumento, TS usa el valor dado en vez de dejarlo en undefined.

saludo?: string (opcional)despedida: string = "Adiós" (por defecto)
Si no lo pasasvale undefinedvale "Adiós"
Necesita if dentro✅ Normalmente sí❌ No
Cuándo usarloEl valor puede no existirSiempre quieres un respaldo

📐 7. Sobrecarga de funciones (overloads)

La sobrecarga permite declarar varias firmas (combinaciones de tipos de entrada/salida) para una misma función, con una sola implementación que cubre todos los casos:

typescript
// 1) Firmas de sobrecarga (solo declaran, no llevan cuerpo)
function combinar(a: string, b: string): string;
function combinar(a: number, b: number): number;

// 2) Implementación única (más general, cubre ambas firmas)
function combinar(a: string | number, b: string | number): string | number {
  if (typeof a === "string" && typeof b === "string") {
    return a + b;   // concatenación
  }
  if (typeof a === "number" && typeof b === "number") {
    return a + b;   // suma numérica
  }
  throw new Error("Tipos incompatibles");
}

console.log(combinar("Hola", " Mundo"));   // Hola Mundo  (TS sabe que devuelve string)
console.log(combinar(10, 20));             // 30          (TS sabe que devuelve number)

Lo importante: solo se puede llamar con las combinaciones declaradas en las firmas. Mezclar tipos falla en compilación (verificado):

typescript
combinar("Hola", 5);
// ❌ error TS2769: No overload matches this call.
ParteCuántasQué hace
Firmas de sobrecargaVarias (sin cuerpo)Declaran las combinaciones válidas de entrada/salida
ImplementaciónUna sola (con cuerpo)Lógica real; sus tipos deben abarcar todas las firmas

📌 TypeScript no permite múltiples implementaciones (eso sería sobrecarga estilo Java/C#). Aquí solo hay múltiples firmas; la única implementación distingue los casos con typeof.

💡 La implementación usa string | number (unión), pero quien llama no ve la unión: ve las firmas. Por eso combinar(10, 20) retorna number directamente, sin necesidad de comprobar el tipo del resultado. Esa es la ventaja frente a escribir solo la función con unión.

🧪 Entrevista: ¿Cómo funciona la sobrecarga en TypeScript vs Java? En Java hay varias implementaciones reales (el compilador elige una). En TS solo existe una implementación en runtime (JavaScript no tiene sobrecarga); las firmas son puro chequeo de tipos y desaparecen al compilar.


💻 PARTE PRÁCTICA

Archivos: 02-Ejercicios/Metodos/metodos.ts y metodos2.ts

bash
cd 02-Ejercicios/Metodos
tsc && node metodos.js && node metodos2.js

Salida:

Mensaje: Hola, este es un mensaje desde la función imprimeMensaje.
Tu resultado es: 15
Hola, Styp!
Buenos días, Styp!
Suma de todos los números: 15
Adiós, Styp!
Hasta mañana, Styp!
  • metodos.tsimprimeMensaje (void) y sumar (retorna number).
  • metodos2.tssaludar (opcional saludo?), sumarTodos (rest + reduce) y despedida (parámetro por defecto). El ejemplo de sobrecarga (combinar) está como apunte comentado en el mismo archivo. Todo verificado. ✅

🏋️ EJERCICIOS CON SOLUCIÓN

Ejercicio 1 — Multiplicar

Escribe multiplicar(a: number, b: number): number que devuelva el producto.

Ver solución
typescript
function multiplicar(a: number, b: number): number {
  return a * b;
}
console.log(multiplicar(4, 5));   // 20

Terminal esperada:

zsh · multiplicar.ts
$ tsc multiplicar.ts
$ node multiplicar.js
20

Ejercicio 2 — Función void

Escribe despedir(nombre: string) que solo imprima Adiós, <nombre>. ¿Qué retorno lleva?

Ver solución
typescript
function despedir(nombre: string): void {   // void: no devuelve nada
  console.log(`Adiós, ${nombre}`);
}
despedir("Ana");   // Adiós, Ana

Terminal esperada:

zsh · despedir.ts
$ tsc despedir.ts
$ node despedir.js
Adiós, Ana

Ejercicio 3 — Precio con descuento opcional

Escribe precio(base: number, descuento?: number): number: si llega el descuento, réstalo; si no, devuelve el precio base.

Ver solución
typescript
function precio(base: number, descuento?: number): number {
  if (descuento) return base - descuento;
  return base;
}
console.log(precio(100));       // 100
console.log(precio(100, 20));   // 80

Terminal esperada:

zsh · precio.ts
$ tsc precio.ts
$ node precio.js
100
80

Ejercicio 4 — Saludo con valor por defecto

Reescribe el saludo usando un parámetro por defecto (en vez de ? + if/else).

Ver solución
typescript
function saludar(nombre: string, saludo: string = "Hola"): string {
  return `${saludo}, ${nombre}!`;
}
console.log(saludar("Styp"));             // Hola, Styp!
console.log(saludar("Styp", "Buenas"));   // Buenas, Styp!

Terminal esperada:

zsh · saludo.ts
$ tsc saludo.ts
$ node saludo.js
Hola, Styp!
Buenas, Styp!

Ejercicio 5 — Promedio con parámetros rest

Escribe promedio(...notas: number[]): number que devuelva el promedio de todas las notas que reciba (cuidado con dividir entre 0 si no llega ninguna).

Ver solución
typescript
function promedio(...notas: number[]): number {
  if (notas.length === 0) return 0;
  const suma = notas.reduce((acc, n) => acc + n, 0);
  return suma / notas.length;
}
console.log(promedio(10, 20, 30));   // 20
console.log(promedio(15, 18));       // 16.5
console.log(promedio());             // 0

Terminal esperada:

zsh · promedio.ts
$ tsc promedio.ts
$ node promedio.js
20
16.5
0

Ejercicio 6 — Sobrecarga: duplicar

Escribe duplicar sobrecargada: con un string devuelve el texto repetido dos veces ("ab""abab"), con un number devuelve el doble (510).

Ver solución
typescript
// Firmas
function duplicar(valor: string): string;
function duplicar(valor: number): number;

// Implementación única
function duplicar(valor: string | number): string | number {
  if (typeof valor === "string") return valor + valor;
  return valor * 2;
}

console.log(duplicar("ab"));   // abab
console.log(duplicar(5));      // 10

Terminal esperada:

zsh · duplicar.ts
$ tsc duplicar.ts
$ node duplicar.js
abab
10

❓ Preguntas y respuestas (autoevaluación)

1. ¿Qué tipo de retorno lleva una función que solo imprime?

void, porque no devuelve un valor útil.

2. ¿Cómo hago un parámetro opcional?

Con ? después del nombre: function f(x?: string). Se puede omitir al llamar.

3. ¿Un parámetro sin marcador es opcional u obligatorio?

Obligatorio. Por defecto todos lo son; si falta, TS da error. Solo ? lo hace opcional.

4. ¿Qué hace ! en TypeScript?

Es el operador non-null assertion: sobre un valor (x!.length) le dice a TS "esto no es null/undefined". NO es un marcador de parámetro (ponerlo en un parámetro es error).

5. ¿Dónde deben ir los parámetros opcionales?

Al final. Un parámetro obligatorio no puede ir después de uno opcional.

6. ¿Diferencia entre saludo?: string y saludo: string = "Hola"?

? = puede faltar (queda undefined). = "Hola" = si falta, usa ese valor por defecto.

7. ¿Qué hace ...numeros: number[] en los parámetros?

Es un parámetro rest: junta todos los argumentos que reciba en un array number[]. Permite llamar la función con cualquier cantidad de números. Va al final.

8. ¿Qué es la sobrecarga de funciones en TypeScript?

Declarar varias firmas (combinaciones válidas de tipos) para una función con una sola implementación, que distingue los casos con typeof. Solo se puede llamar con las combinaciones declaradas; mezclar tipos da TS2769: No overload matches this call.

9. ¿Puedo escribir dos implementaciones de combinar, una para strings y otra para numbers?

No. TS solo permite múltiples firmas; la implementación es una sola (JavaScript en runtime no tiene sobrecarga). Dos function combinar(...) { } = error de identificador duplicado.

📎 Apuntes relacionados

➡️ Siguiente

Objetos e interfaces (modelar datos con interface / type).