Tipos de Funções e Funções Arrow em TypeScript
Tipo de Função
Cada função possui um tipo, assim como variáveis comuns. O tipo de uma função é, na verdade, uma combinação dos tipos de seus parâmetros e do tipo do valor retornado. De forma geral, a definição do tipo de uma função é representada assim:
(parâmetro1: tipo, parâmetro2: tipo, ...parâmetroN: tipo) => tipoResultado;Entre parênteses, temos a lista de parâmetros e seus respectivos tipos, separados por vírgula. Após os parâmetros, o operador => indica o tipo do resultado retornado pela função.
Por exemplo, considere a seguinte função:
function hello() {
console.log("Hello TypeScript");
}Esta função não possui parâmetros e não retorna nada. Se uma função não retorna nada, o tipo de seu valor de retorno é void. Portanto, a função hello tem o tipo:
() => void;Utilizando o tipo de função, podemos definir variáveis, constantes e parâmetros que seguem esse tipo. Por exemplo:
function hello() {
console.log("Hello TypeScript");
}
const message: () => void = hello;
message();Neste exemplo, a variável message representa qualquer função que não recebe parâmetros e não retorna nada.
Outro exemplo seria uma função que recebe parâmetros e retorna um resultado:
function sum(x: number, y: number): number {
return x + y;
}Esta função tem o tipo (x: number, y: number) => number, ou seja, ela aceita dois parâmetros do tipo number e retorna um valor também do tipo number.
Também podemos definir variáveis desse tipo de função:
let op: (x: number, y: number) => number;Ou seja, a variável op pode representar qualquer função que recebe dois números e retorna um número. Por exemplo:
function sum(x: number, y: number): number {
return x + y;
}
function subtract(a: number, b: number): number {
return a - b;
}
let op: (x: number, y: number) => number;
op = sum;
console.log(op(2, 4)); // 6
op = subtract;
console.log(op(6, 4)); // 2Neste caso, inicialmente a variável op faz referência à função sum. Então, ao chamar op(2, 4), ela na verdade chama sum(2, 4). Em seguida, op passa a apontar para a função subtract.
Funções como Parâmetros de Outras Funções
O tipo de uma função pode ser usado como o tipo de uma variável, mas ele também pode ser utilizado para definir o tipo de um parâmetro em outra função:
function sum(x: number, y: number): number {
return x + y;
}
function multiply(a: number, b: number): number {
return a * b;
}
function mathOp(x: number, y: number, op: (a: number, b: number) => number): number {
return op(x, y);
}
console.log(mathOp(10, 20, sum)); // 30
console.log(mathOp(10, 20, multiply)); // 200Aqui, na função mathOp, o terceiro parâmetro representa uma função que recebe dois parâmetros do tipo number e retorna um valor do tipo number. Assim, ao chamar mathOp, podemos passar, por exemplo, as funções sum ou multiply, que correspondem ao tipo (a: number, b: number) => number.
Se um determinado tipo de função for usado com muita frequência, é mais prático definir um alias para ele:
type Operation = (a: number, b: number) => number;
function mathOp(x: number, y: number, op: Operation): number {
return op(x, y);
}
const sum: Operation = function (x: number, y: number): number {
return x + y;
};
console.log(mathOp(10, 20, sum)); // 30Aqui, o tipo (a: number, b: number) => number é associado ao alias Operation, que pode ser utilizado para definir variáveis e parâmetros.
Funções Arrow
Em TypeScript, também podemos utilizar funções arrow (ou funções de seta) para definir funções. As funções arrow seguem a sintaxe (parâmetros) => corpo da função. Por exemplo:
const sum = (x: number, y: number) => x + y;
const result = sum(15, 35); // 50
console.log(result);Os tipos dos parâmetros podem ser omitidos:
const sum = (x, y) => x + y;
const result = sum(15, 35); // 50
console.log(result);Se uma função arrow não requer parâmetros, utiliza-se parênteses vazios. Se a função tiver apenas um parâmetro, os parênteses podem ser omitidos:
const square = (x) => x * x;
const hello = () => "hello world";
console.log(square(5)); // 25
console.log(hello()); // hello worldSe o corpo da função contiver múltiplas instruções, é necessário utilizar chaves para delimitá-las:
const sum = (x: number, y: number) => {
x *= 2;
return x + y;
};
const result = sum(15, 35); // 65
console.log(result);Funções arrow podem ser passadas como argumento para outras funções, que esperam funções como parâmetros:
function mathOp(x: number, y: number, operation: (a: number, b: number) => number): number {
const result = operation(x, y);
return result;
}
console.log(mathOp(10, 20, (x, y) => x + y)); // 30
console.log(mathOp(10, 20, (x, y) => x * y)); // 200