Fecha publicación: 25 sept 2021

TypeScript Funciones

Tipar funciones en TypeScript es muy sencillo, consiste en especificar los tipos de los argumentos que recibe y el tipo de dato que devuelve (el retorno).

Manos a la obra

Funciones estándares

Vamos a crearnos una función sencilla, vamos a llamarla shout (gritar) y tendrá dos argumentos de entrada un texto y un booleano para indicar si queremos mostrarlo por pantalla en mayúscula o minúscula:

function shout(text, upperCase) {
  return (upperCase ? text.toUpperCase() : text) + "!!!";
}

Lo que estamos haciendo en la función es:

  • Le pasamos un parámetro de tipo string con un texto, y un segundo parámetro de tipo booleano para indicar si queremos que el grito se genere en mayúsculas.
  • En el return utilizamos un ternario y en caso de que upperCase sea true ponemos el texto en mayúsculas.
  • Al final le añadimos tres signos de exclamación.

Ahora mismo no tenemos ningún tipo de ayuda con TypeScript, vamos a tipar la función, ¿Cómo tipamos los argumentos? Le indicamos después de cada parámetro el tipo:

- function shout(text, upperCase) {
+ function shout(text : string, upperCase : boolean) {

  return (upperCase ? text.toUpperCase() : text) + "!!!";
}

Aquí le estamos indicando que text es un string y que uppercase es un booleano.

- function shout(text, upperCase) {
+ function shout(text : string, upperCase : boolean) {
    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

Vamos a tipar ahora el retorno de la función, si pones el ratón encima de la función verás que él sólo lo infiere ahora que conoce los parametros de entrada, aún así es buena idea indicarle el retorno, así evitamos que si por ejemplo en el return nos equivocamos y devuelve otra cosa, nos lleve a un código erróneo, para ello a la derecha de la lista de argumentos, entre el segundo parentesis y la llave de apertura de la función, añadimos el carácter : y el tipo string:

- function shout(text : string, upperCase : boolean) {
+ function shout(text : string, upperCase : boolean) : string {
    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

Ahora sí le indicamos explícitamente que la función devuelve un string.

Al hacer uso de está función, fíjate que en el momento que hago la llamada de la función, me muestra un pop up en el que me indica el tipo de la función y que devuelve.

Se muestra un popup con el tipado de la función

Si empiezo a teclear, me avisará que tengo que introducir los argumentos esperados y con el tipo correcto, por ejemplo:

console.log(shout("hola", true));

Fat Arrow

Está sería la función en formato clásico, ¿Como sería en formato arrow function? El tipado no cambia, sólo tenemos que convertir sintaxis, la función quedaría:

- function shout(text : string, upperCase : boolean) : string {
+ const shout = (text : string, upperCase : boolean) : string => {

    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

Si lo ejecutamos volvemos a tener el mismo resultado.

Parámetros opcionales y valores por defecto

Al igual que sucedía con las propiedades en los interfaces aquí tenemos dos modificadores muy interesantes para los argumentos de funciones, podemos hacerlos opcionales o podemos hacerlos valores por defecto.

Para hacer un argumento opcional simplemente basta con colocar la interrogación a la derecha de su nombre, al igual que hacíamos con las propiedades en los interfaces, siguiendo el caso anterior podemos hacer opcional el parámetro upperCase (por defecto ese valor tendrá undefined si no se informa), y ahora podemos llamar a la función con un sólo parámetro (en este caso el ternario comprobará que el valor es undefined y nos devolverá el texto en minúsculas).

- const shout = (text : string, upperCase : boolean) : string => {
+ const shout = (text : string, upperCase? : boolean) : string => {
    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

- console.log(shout("hola", true));
+ console.log(shout("hola"));

Igualmente podemos indicar valores por defecto a un argumento, vamos a eliminar el interrogante opcional, e indicarle que upperCase por defecto tendrá el valor true, para eso a la derecha de su tipado ponemos = true.

De esta manera cuando invoquemos a esta función con un sólo parámetro, nos pondrá el texto en mayúsculas (ya que el parámetro upperCase si no se informa vale true por defecto):

+ type ShoutFunction = (text:string, upperCase: boolean) => string

- const shout = (text : string, upperCase : boolean = true) : string => {
+ const shout : ShoutFunction = (text, upperCase = true) => {

    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

console.log(shout("hola"));

Una tema importante a tener en cuenta, un parámetro no puede ser opcional y tener una asignación por defecto a la vez, ya que entrarían en conflicto (el valor por defecto ya implica que este argumento es opcional).

Alias

Hasta ahora hemos visto el tipado de las funciones incluido en su propia definición, también tenemos la posibilidad de extraerlo fuera, para esto haremos uso de los alias esto es útil para reutilizar el tipado de una función tantas veces como lo necesite.

Para crear una alias escribimos el operador type y a continuación un nombre, por ejemplo ShoutFunction (al ser un tipo es aconsejable que lo pongamos con Pascal Case, es decir la S en mayúsculas y la F en mayúsculas), le añadimos un igual y a continuación expresamos el tipado de la función que tenemos debajo:

type ShoutFunction = (text: string, upperCase: boolean) => string;

Es importante que tengamos en cuenta que hemos creado un alias esto no es un tipo.

Para hacer uso de este alias simplemente decimos que la variable shout es de tipo ShoutFunction y esto me va a permitir eliminar el tipado integrado que tenían en la función:

type ShoutFunction = (text: string, upperCase: boolean) => string;

+ const shout = (text : string, upperCase : boolean = true) : string => {
- const shout = (text : string, upperCase? : boolean) : string => {
    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

console.log(shout("hola"));

Fíjate que aquí el retorno lo establecemos con la flecha y le decimos que es de tipo string.

Los valores por defecto si los hemos dejado en la implementación, en el alias no podemos asignarlos, como mucho, podemos decir en el que la función es opcional.

- type ShoutFunction = (text: string, upperCase: boolean) => string;
+ type ShoutFunction = (text: string, upperCase?: boolean) => string;


const shout = (text : string, upperCase : boolean = true) : string => {
    return (upperCase ? text.toUpperCase() : text) + "!!!";
}

console.log(shout("hola"));

La utilidad más evidente de los alias es poder reutilizar los tipos, por ejemplo yo podría crearme ahora un interfaz al que voy a llamar TextModificator y dentro una de las entradas añadir una propiedad shout, que sea de tipo función, y la podemos tipar usando el alias (no tengo que volver a copiar todo el tipo a la función)

interface TextModificators {
  shout: ShoutFunction;
}

Sobrecarga

Por último el tipado de funciones se puede sobrecargar, veamos en que consiste eso, supongamos la función showLog que acepta un parámetro y nos lo muestra por consola:

function showLog(x) {
  console.log(x);
}

showLog("hola");

De momento al no estar tipado, x puede ser cualquier cosa, ¿Qué pasa si yo quiero tipar esta función y quiero que la x sea o bien un string o un número? puedo hacer una sobrecarga, es decir justo encima de la función, puedes poner la definición de la función tipandola, en este caso añadimos dos sobrecargas, una para aceptar como parámetro de entrada el tipo string y otr para el tipo number:

+ function showLog(text: string) : void;
+ function showLog(number: number) : void;
function showLog(x) {
  console.log(x);
}

showLog("hola");

Aquí la implementación es la de la función, pero le proporciono diferentes firmas con diferentes tipados, cuando haga la llamada de showLog automáticamente me da dos firmas (dos sobrecargas), o bien me pasas un número o me pasas un string en el primer parámetro.

Dos firmas popup

Importante para que la sobrecarga funcione, el número de argumentos tanto de la implementación como de todas las sobrecargas tiene que ser el mismo, lo que si nos permite es cambiar el nombre de sus argumentos en cada sobrecarga y el tipo.

¿Te apuntas a nuestro máster?

Si te ha gustado este ejemplo y tienes ganas de aprender Front End guiado por un grupo de profesionales ¿Por qué no te apuntas a nuestro Máster Front End Online Lemoncode? Tenemos tanto edición de convocatoria con clases en vivo, como edición continua con mentorización, para que puedas ir a tu ritmo y aprender mucho.