anserran.dev

Funciones en TypeScript

Definición de funciones

En TypeScript puedes definir funciones así:

function calculateTotalPrice(basePrice: number, taxes: number) {
  return basePrice + taxes;
}

const totalPrice = calculateTotalprice(100, 21.2);
// ^ number

Nota que los parámetros de entrada basePrice y taxes tienen definido su tipo de manera explícita (number), pero que el tipo del resultado de la función no está definido en ninguna parte. Como siempre que el contexto lo permite, TypeScript lo infiere dado el resto de tipos, deduciendo que el resultado es un number dado que es la suma de otros dos number.

Pero también puedes ser explícitos con el tipo del resultado cuando sea necesario:

function calculateTotalPrice(
  basePrice: number,
  taxes: number,
): number {
  return basePrice + taxes;
}

void

Por otro lado, también es posible definir funciones que no devuelvan nada:

function sayHello() {
  console.log("Hola.");
}

Para estas funciones podría esperarse que TypeScript infiriera undefined como el tipo del resultado, pero no.

TypeScript provee de un tipo concreto para representar el resultado vacío de funciones que no declaran un return. Es el tipo void, que puede agregarse de manera explícita si queremos evitar que en el futuro esta función devuelva algo cuando no debería:

function sayHello(): void {
  console.log("Hola.");
}

Funciones flecha (arrow functions)

Existe una manera alternativa de definir funciones:

const calculateTotalPrice = (
  basePrice: number,
  taxes: number,
): number => {
  return basePrice + taxes;
};

Se las conoce como funciones flecha (arrow function) porque, bueno, tienen una flecha precediendo la definición de su cuerpo.

En el ejemplo anterior, como la función solo tiene una línea podríamos ahorrarnos el return:

const calculateTotalPrice = (
  basePrice: number,
  taxes: number,
): number => basePrice + taxes;

También podríamos ahorrarnos el tipo de salida de la función, porque TypeScript sigue pudiendo inferirlo.

Esta sintaxis es muy útil cuando queremos generar funciones que están muy pegadas al contexto en el que se utilizan:

const products = [
  { name: "Libro", price: 15 },
  { name: "Aplicación", price: 9.99 },
];
const sortedProducts = products.sort(
  (p1, p2) => p1.price - p2.price,
);

Nota como aquí dejamos que TypeScript infiera todos los tipos.

sort recibe una función que determina el orden de dos productos. En esta función no necesita que p1 y p2 tengan tipos definidos porque TypeScript los infiere a partir de los elementos de la lista.

TypeScript solo te obliga a ser explícito con los tipos de aquellos valores cuyo tipo no puede inferir a partir del contexto existente.

Eso sí, ya sea por exactitud o legibilidad, siempre puedes añadir los tipos de manera explícita a cualquier variable.

Funciones de orden superior

También puedes crear funciones que reciban como argumentos otras funciones, y/o devolver funciones como resultado. A estas funciones se las denomina funciones de orden superior (higher-order functions):

const parsers = {
  json: (value: string) => JSON.parse(text),
  txt: (value: string) => text,
};

function parseText(text: string, parse: (value: string) => any) {
  return parse(text);
}

const fileExt = "json";
const fileContent = `{ "price": 10.50 }`;

const value = parseText(fileContent, parsers[fileExt]);
console.log(value.price);

parseText es una función de orden superior que recibe una función como argumento, parse . Esta función tiene un parámetro de entrada value y un resultado any. Para entender este código no es suficiente con saber que any puede representar cualquier tipo.

Las funciones de orden superior son particularmente útiles para programación funcional.

Siguiente