Anotaciones de tipo en funciones
// Función básica con tipos
function add(a: number, b: number): number {
return a + b;
}
// Función flecha con tipos
const multiply = (a: number, b: number): number => {
return a * b;
};
// Inferencia del tipo de retorno
function subtract(a: number, b: number) {
return a - b; // tipo de retorno inferido como number
}
// Tipo de retorno void
function logMessage(message: string): void {
console.log(message);
}
// Tipo de retorno never (lanza error o bucle infinito)
function fail(message: string): never {
throw new Error(message);
}
Parámetros opcionales y por defecto
// Parámetro opcional (debe ir después de los requeridos)
function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`;
}
greet("Alice"); // "Hello, Alice!"
greet("Bob", "Hi"); // "Hi, Bob!"
// Parámetro por defecto
function greetWithDefault(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
greetWithDefault("Alice"); // "Hello, Alice!"
greetWithDefault("Bob", "Hi"); // "Hi, Bob!"
// Por defecto con inferencia de tipo
function createUser(name: string, role = "user") {
// role se infiere como string
return { name, role };
}
Parámetros rest
// Parámetros rest
function sum(...numbers: number[]): number {
return numbers.reduce((acc, num) => acc + num, 0);
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15
// Rest con otros parámetros
function buildName(firstName: string, ...restOfName: string[]): string {
return firstName + " " + restOfName.join(" ");
}
buildName("John", "Paul", "Jones"); // "John Paul Jones"
// Parámetros rest tipados con tuplas
function readButtonInput(...args: [string, number, ...boolean[]]): void {
const [name, version, ...flags] = args;
console.log(name, version, flags);
}
Expresiones de tipo de función
// Expresión de tipo de función
type MathOperation = (a: number, b: number) => number;
const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;
// Usar en otros tipos
interface Calculator {
add: MathOperation;
subtract: MathOperation;
multiply: MathOperation;
divide: MathOperation;
}
// Tipos para callbacks
type Callback = (error: Error | null, result?: string) => void;
function fetchData(url: string, callback: Callback): void {
// ...
callback(null, "data");
}
// Métodos de array con callbacks tipados
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((n: number): number => n * 2);
// Alias de tipo para manejador de eventos
type ClickHandler = (event: MouseEvent) => void;
Funciones genéricas
// Función genérica básica
function identity<T>(arg: T): T {
return arg;
}
identity<string>("hello"); // tipo explícito
identity(42); // inferido como number
// Genérico con restricciones
function getLength<T extends { length: number }>(arg: T): number {
return arg.length;
}
getLength("hello"); // 5
getLength([1, 2, 3]); // 3
// getLength(123); // Error: number no tiene length
// Múltiples parámetros de tipo
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
const result = pair("hello", 42); // [string, number]
// Genérico con tipo por defecto
function createArray<T = string>(length: number, value: T): T[] {
return Array(length).fill(value);
}
createArray(3, "x"); // string[] (explícito)
createArray(3, 42); // number[] (inferido)
createArray<>(3, "x"); // string[] (por defecto)
Sobrecargas de funciones
// Sobrecargas de funciones
function makeDate(timestamp: number): Date;
function makeDate(year: number, month: number, day: number): Date;
function makeDate(yearOrTimestamp: number, month?: number, day?: number): Date {
if (month !== undefined && day !== undefined) {
return new Date(yearOrTimestamp, month - 1, day);
}
return new Date(yearOrTimestamp);
}
makeDate(1609459200000); // Desde timestamp
makeDate(2024, 1, 15); // Desde año, mes, día
// makeDate(2024, 1); // Error: no hay sobrecarga válida
// Sobrecargas con distintos tipos de retorno
function getValue(key: "name"): string;
function getValue(key: "age"): number;
function getValue(key: "active"): boolean;
function getValue(key: string): string | number | boolean {
const data: Record<string, string | number | boolean> = {
name: "Alice",
age: 30,
active: true
};
return data[key];
}
const name = getValue("name"); // string
const age = getValue("age"); // number
const active = getValue("active"); // boolean
Parámetro this
// Tipo explícito de this
interface User {
name: string;
greet(this: User): string;
}
const user: User = {
name: "Alice",
greet() {
return `Hello, I'm ${this.name}`;
}
};
user.greet(); // "Hello, I'm Alice"
// const callback = user.greet;
// callback(); // Error: contexto 'this' de tipo 'void'
// this en métodos de clase
class Counter {
count = 0;
// La función flecha preserva 'this'
increment = () => {
this.count++;
};
// El método normal necesita binding
decrement() {
this.count--;
}
}
Ejemplos prácticos
// Función de fetch para API
async function fetchUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
// Manejador de eventos
function handleClick(event: React.MouseEvent<HTMLButtonElement>): void {
console.log("Clicked:", event.currentTarget);
}
// Utilidad debounce
function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeoutId: ReturnType<typeof setTimeout>;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func(...args), wait);
};
}
// Función de orden superior
function withLogging<T extends (...args: any[]) => any>(fn: T): T {
return ((...args) => {
console.log("Calling with:", args);
const result = fn(...args);
console.log("Result:", result);
return result;
}) as T;
}
Puntos clave
- • Tipa parámetros y valores de retorno
- • Usa
? para parámetros opcionales
- • Usa parámetros rest con arrays tipados
- • Las funciones genéricas permiten reutilización segura
- • Las sobrecargas manejan múltiples firmas
- • Sé explícito con
this cuando sea necesario