Existen diferentes formas de definir o declarar una función en Javascript, y siendo Typescript un superset, no es diferente, ahora tienes muchas más formas o sintaxis para cumplir el mismo objetivo.
En este breve tutorial encontrarás una lista de las formas más comunes que encontrarás a la hora de definir/declarar una función en Typescript.
Primero, para crear una función en Javascript existen 4 formas base:
Declaración de función
sponsor
Tu producto o servicio podría estar aquí
function multiplicar(a,b) {
return a * b
}
Expresión anonima
const multiplicar = function(a,b) {
return a * b;
}
Expresion de función con nombre
const multiplicar = function multiplicar(a,b) {
return a * b;
}
Función flecha / Arrow function
const multiplicar = (a, b) => {
return a * b;
}
Retorno implícito
const multiplicar = (a, b) => a * b;
El objetivo de agregar Typescript al stack es definir los tipos tanto de los argumentos de la función, como del valor de retorno (aunque este muchas veces puede ser inferido).
Comencemos por agregar tipos a los métodos mencionados
Declaración de función
// Tipo de Retorno inferido
function multiplicar(a: number,b: number) {
return a * b
}
// Tipo de Retorno definido
function multiplicar(a: number,b: number): number {
return a * b
}
Expresión anonima
const multiplicar = function(a: number,b: number): number {
return a * b;
}
Expresion de función con nombre
const multiplicar = function multiplicar(a: number,b: number): number {
return a * b;
}
Función flecha / Arrow function
const multiplicar = (a: number, b: number): number => {
return a * b;
}
Retorno implícito
const multiplicar = (a:number, b: number): number => a * b;
También es posible extraer la definición de los tipos e incluirlos en una sección diferente que la propia función.
sponsor
Tu producto o servicio podría estar aquí
const multiplicar: (a:number, b: number): number = (a,b)=> a * b;
En este ejemplo el tipo de la función es definido antes de la declaración de la misma.
También es posible extraer el tipo de la función para mejorar legibilidad o incluso para utilizarlo en otro lugar.
type MulFn = (a:number, b: number) => number
const multiplicar: MulFn = (a,b)=> a * b;
Esto también puede ser logrado utilizando la sintaxis de objeto
type MulFn = {
(a:number, b: number): number
}
const multiplicar: MulFn = (a,b)=> a * b;
O también utilizando una interfaz
interface MulFn {
(a:number, b: number): number
}
const multiplicar: MulFn = (a,b)=> a * b;
Parámetro opciones y parámetros por defecto
Una caracterítica interesante y muy útil al definir los tipos de tus funciones es la posibilidad de declarar que parámetros son opcionales.
const multiplicar: (a:number, b?: number): number = (a,b)=> a * (b ?? 1);
Este ejemplo permite que el parámetro b
no se utilice o sea undefined
Otra forma de crear opcionalidad de parámetros es definir su valor por defecto. Typescript tratará dicho parámetro como un parámetro opcional
const multiplicar: (a:number, b: number) => number = (a,b = 1)=> a * b;
multiplicar(2) // = 2
multiplicar(2, undefined) // 2
Esto implica que puedes “imitar” la opcionalidad de parámetros sin importar el orde, por ejemplo haciendo que el primer parámetro sea “opcional”.
const multiplicar: (a:number = 1, b: number): number = (a,b)=> a * b;
multiplicar(undefined,2) // = 2
Async
Las funciones asíncronas en Typescript funcionan de la misma forma que en Javascript, solo que el tipo de retorno es en efecto una Promise
genérica.
async function somePromise(a: number, b: string): Promise<number> {
// logic
}
const somePromise = (a: number, b: string): Promise<number> => {
// logic
}
Generics
Generics es en mi opinión una de las herramientas más poderosas de Typescript ya que permite total flexibilidad en la forma en que defines tus tipos, en el caso de declarar funciones lo puedes hacer de la siguiente forma
function someFunction<GenericType>(a: GenericType): Array<GenericType> {
// some logic
}
En este ejemplo la función toma un parámetro tipo GenericType
y retorna un arreglo del mismo tipo, ¿cómo se usa?
someFunction<number>(10) // [10]
Esto también se puede lograr con arrow functions
pero, existe un problema: Si estás trabajando con React (o cualquier framework que acepte algo similar a JSX) el compilador de Typescript no sabrá si estás usando JSX
o un Generic
, por lo que necesitas agregar algo que le permita identificar que se trata de un genérico
const someFunction = <GenericType extends unknown>(a: GenericType): Array<GenericType> => {
//some logic
}
Conclusión
Existen varias formas de definir funciones, he dejado muchas afuera pero creo que estas son las formas más generales. Algunas que no han sido mecionadas:
- Type Guards
- Assertions
- Generators
- Function Overloads
- Modules
- Classes
sponsor
Tu producto o servicio podría estar aquí
😃 Gracias por leer!
Te pareció interesante? Encuentra más contenido similar uniendote al Newsletter o siguiendome en Twitter.