Fundamentos de TypeScript 🦆| #11: Type Function
Tags: typescript, spanish, webdev, beginners
Published: 2022-01-21 14:11:34

TypeScript tiene un tipo muy interesante que es ridículamente útil. Este tipo es `Function` (con mayúscula). Pero, ¿para qué nos sirve este tipo de dato?

`Function` indica a **una variable que está solo puede contener una referencia a una funcion**, caso contrario arroja un hermoso error.

Veamos un ejemplo:

```ts
const filtrarNombres = (arr:string[]):string[] => {
  return arr.filter((item) => item === "Carlos" || item === "Susana")
}

const nombres = ["Carlos", "Juan", "Pedro", "Susana", "Camilo"]
let resultado = filtrarNombres(nombres);
console.log(resultado) // ["Carlos", "Susana"]
```

La función `filtrarNombres` regresa solo a mis amigos que tengan por nombre "Carlos" o "Susana". Muy fácil. Esta salida la almacenamos en la variable `resultado` para luego mostrarla por consola.

Pero que pasa si antes de imprimir el `resultado` cambiamos su valor:

```ts
const filtrarNombres = (arr:string[]):string[] => {
  return arr.filter((item) => item === "Carlos" || item === "Susana")
}

const nombres = ["Carlos", "Juan", "Pedro", "Susana", "Camilo"]
let resultado = filtrarNombres(nombres);
resultado = ["Hola mundo"];
console.log(resultado); // ["Hola mundo"]
```
Ahora la función se contaminó, y no regresa lo que yo esperaba.

Podemos arreglar este problema haciendo que la variable `resultado` solo pueda recibir una referencia a una función.

```ts
const filtrarNombres = (arr:string[]):string[] => {
  return arr.filter((item) => item === "Carlos" || item === "Susana")
}

const nombres = ["Carlos", "Juan", "Pedro", "Susana", "Camilo"]
let resultado: Function;
resultado = filtrarNombres;
console.log(resultado(nombres)); // ["Carlos", "Susana"]

```

Ahora `resultado` es una variable que solo puede almacenar una función, esto hace que el código sea menos susceptible a errores y bugs.
Si intentamos guardar algo que no sea una función en `resultado` obtendremos un error.

Esta implementación es buena, pero aún tiene un problema, `resultado` aceptará cualquier función.

```ts
const filtrarNombres = (arr:string[]):string[] => {
  return arr.filter((item) => item === "Carlos" || item === "Susana")
}

const saludo = () => console.log("Hola mundo")

const nombres = ["Carlos", "Juan", "Pedro", "Susana", "Camilo"]
let resultado: Function;
resultado = saludo;
console.log(resultado(nombres)); // "Hola mundo"
```
Es posible guardar la función `saludo` en `resultado` puesto que es una función común y corriente, pero esto mancha nuestro programa nuevamente porque ya no obtenemos lo que esperábamos.

Para poder pulir este codigo un poco mas podemos especificar mas concretamente las características que debe tener las funciones que puede aceptar `resultado` indicando al programa cuantos parámetros debe tener, el tipo de dato de estos parámetros y su tipo de regreso:

En vez de esto

```ts
let resultado: Function;
```
Hacemos esto

```ts
let resultado: (arreglo:string[]) => string[]
```
Ahora `resultado` solo recibirá funciones que tengan exactamente un parámetro, dicho parámetro debe ser si o si un arreglo de strings y finalmente la función debe regresar otro arreglo de strings. Ahora todo está mucho más claro y específico.

Ya no es posible guardar `saludo` en `resultado` por que no cumple con ninguna de las restricciones que le pusimos.

El código final se veria de la siguiente manera:

```ts
const filtrarNombres = (arr:string[]):string[] => {
  return arr.filter((item) => item === "Carlos" || item === "Susana")
}

const saludo = () => console.log("Hola mundo")

const nombres = ["Carlos", "Juan", "Pedro", "Susana", "Camilo"]
let resultado: (arreglo:string[]) => string[]
resultado = filtrarNombres;
console.log(resultado(nombres)); // ["Carlos", "Susana"]
```

## **Conclusiones**
- El `Type Function` es super útil para restringir que una variable solo puede almacenar funciones.
- Podemos usar el tipo `Function` para lograr esto, pero la desventaja es que es muy general y nuestras variables podrán soportar cualquier tipo de función.
- Podemos declarar el tipo de la función en concreto para indicarle la cantidad de parámetros, sus tipos de datos y su valor de retorno. En otras palabras como si le pusiéramos un candado a la variable para que solo reciba funciones concretas y específicas.


## **Referencias**
{% youtube BwuLxPH8IDs %}