Este post é o segundo de uma série de 6 posts sobre TypeScript. Veja os detalhes dos posts aqui.

Post anterior: TypeScript – Introdução

No TypeScript, podemos definir funções tipadas. Seus argumentos e seu retorno é tipado. Isso garante um maior controle e segurança da função. Vamos ver um exemplo de uma função que soma dois números.

window.onload = () => {
    function sum(number1: number, number2: number): number {
        return number1 + number2;
    }

    var value: number = sum(10, 20);
    console.log("sum", value);
};

Acima, temos uma função com o nome “sum”, ela por sua vez, exige 2 argumentos (number1 e number2), ambos do tipo “number”. E a função denota um retorno do tipo “number” também, através do trecho “: number {“.
Já no corpo da função, é retornado a soma dos argumentos.
Mais abaixo, fazemos uso da função, atribuindo o retorno da função “sum” para variável do tipo “number”, com o nome “value”. E por fim, imprimimos o valor e “value” no console.

Function Type

Também podemos definir um tipo, baseado em uma função. Primeiro definimos a assinatura e seu retorno. Depois, devemos definir sua implementação. Vamos trabalhar com a mesma implementação do primeiro exemplo.

window.onload = () => {
    var sum: (baseValue: number, increment: number) => number;
    sum = function (number1: number, number2: number): number {
        return number1 + number2;
    };

    var value: number = sum(10, 20);
    console.log("sum", value);
};

Acima, atribuímos um “tipo função” a variável “sum”, cujo o retorno deve ser do tipo “number” e deve possuir 2 argumentos. Qualquer tentativa de definir o valor de “sum” diferente do esperado, irá gerar um erro não esperado.
Logo abaixo, definimos o valor da variável “sum” e sua implementação. Que nada mais é a soma dos argumentos, seguido do retorno da soma.
Em seguida, fazemos uso da function type “sum”, e imprimimos seu valor no console.
A function type, também poderia ser declarada em uma mesma linha.

window.onload = () => {
    var sum: (baseValue: number, increment: number) => number = function (number1: number, number2: number): number {
        return number1 + number2;
    };

    var value: number = sum(10, 20);
    console.log("sum", value);
};

Parâmetros opcionais

O TypeScript da condição de declarar parâmetros opcionais em uma function. Para isso, basta utilizar o carácter “?” antes de “:” no parâmetro.
Ainda trabalhando com a função “sum”, vamos adicionar um terceiro parâmetro, porem ele deve ser opcional.

window.onload = () => {
    function sum(number1: number, number2: number, number3?: number): number {
        return number1 + number2 + (number3 || 0);
    };

    var value: number = sum(10, 20, 9);
    console.log("sum", value);
};

Acima, adicionamos o parâmetro “number3” do tipo “number”. Repare que ele possui um “?”. Isso denota que ele pode não possuir valor. Já no corpo da função, verificamos se o argumento de nome “number3”, possui valor, do contrário, o zero deve permanecer, ou seja, somar os dois primeiros argumentos mais zero, não afetará o resultado final, caso o terceiro parâmetro seja omitido.

Parâmetros padrões

Também podemos definir um valor padrão para o argumento da função. Vamos deixar a função parecida com o exemplo anterior. Com diferença que iremos definir o valor zero como padrão, para o argumento “number3”.

window.onload = () => {
    function sum(number1: number, number2: number, number3: number = 0): number {
        return number1 + number2 + number3;
    };

    var value: number = sum(10, 20);
    console.log("sum", value);
};

Acima, definimos que o argumento “number3” tem como valor padrão zero, caso o argumento seja omitido, o valor padrão sera zero, e não irá interferir no resultado final da soma.

Rest Parameters

O TypeScript da condição de definir um argumentos que pode ser utilizado como um array de um tipo qualquer. Porem, pode ser utilizado apenas uma vez, e deve ser sempre o último argumento. Este recurso se chama “Rest Parameters”. Por convenção, o nome do parâmetro deve ser precedido por “…” e seu tipo deve ser um array. No exemplo, vamos trabalhar com a função “sum”. Devemos somar os dois primeiros argumentos, e somar os demais (não sabemos quantos número virão neste array, então devemos percorre todos os itens do array).

window.onload = () => {
    function sum(number1: number, number2: number, ...numberAdds: number[]): number {
        var result: number = number1 + number2;
        for (var i: number = 0; i < numberAdds.length; i++)
            result += numberAdds[i];

        return result;
    };

    var value: number = sum(10, 20, 30, 40, 89);
    console.log("sum", value);
};

Acima, declaramos a função com o nome “sum”. Que irá retornar um “number”. Ela possui 3 argumentos. O primeiro e o segundo, são do tipo “number”. E o terceiro é um parâmetro “Rest Parameters”, ou seja, um array de “number”. Repare que ele é o último argumento.
Já no corpo da função, declaramos um variável como o nome “result”, cujo o tipo é “number”. E atribuímos o resultado da soma dos dois primeiros argumentos.
Em seguida, fizemos um “for”, para percorrer todos os itens do argumento. E incrementamos o item do array, na variável “result”.
E por fim, retornamos o valor da variável “result”.
Repare que podemos utilizar “sem limite” os argumentos da função “sum”.

Sobrecarga de função

O TypeScript permite sobrecarregar uma mesma função / método. Para isso, devemos declarar suas assinaturas de função, e fazer uma única implementação. No exemplo, vamos criar uma função para calcular a área de um quadrado ou retângulo.

window.onload = () => {
    function calculateArea(x: number): number; // Está função deverá calcular a área do quadrado
    function calculateArea(x: number, y: number): number; // Está função deverá calcular a área do retângulo
    function calculateArea(x: number, y?: number): number {
        return x * (y > 0 ? y : x);
    }

    var areaSquare: number = calculateArea(3);
    var areaRectangle: number = calculateArea(3, 4);
    console.log("Área do quadrado", areaSquare);
    console.log("Área do retângulo", areaRectangle);
};

Acima, definimos que devemos ter 2 assinaturas de função. A primeira deve ser responsável por calcular a área do quadrado. A segunda, deve calcular a área do retângulo. A terceira declaração, define a implementação de fato. Repare que todos os parâmetros, estão presentes na assinatura da função, porem com “?”. Isso significa que todas as chamadas para a função “calculateArea”, irão convergir nesta implementação (até porque, as demais funções, não possuem implementação, somente assinatura).
A regra é simples, caso o argumento “y” seja maior que zero, multiplicamos o valor do argumento “x” por “y”, isso calculará a área do retângulo. Caso contrário, multiplicamos o parâmetro “x” por ele mesmo, ou seja, consideramos que a área é quadrada (e obviamente, possui valores iguais).
E por fim, utilizamos a duas sobrecargas.

Arrow Function

Para uma linguagem que afirma ser funcional, você tende a digitar bastante no JavaScript. Com “Arrow function”, permite abreviar a declaração da função. Vamos ver o exemplo da função “sum”.

window.onload = () => {
    var sum = (number1: number, number2: number) => {
        return number1 + number2;
    };

    var sum2 = (number1: number, number2: number) => number1 + number2;

    var resultSum: number = sum(3, 3);
    var resultSum2: number = sum2(3, 3);
    console.log("Resultado da soma", resultSum);
    console.log("Resultado da soma", resultSum2);
};

Acima, temos uma “function type”, como vimos anteriormente, com o nome “sum”. Nela definimos a assinatura da função e logo em seguida definimos o corpo da função, que fica entre “{…}”.
Logo abaixo, definimos um segundo modo de declarar uma “arrow function”. A diferença é que fizemos a soma das variáveis, logo depois de “=>”. Neste caso, não precisa de “return”.

Continue lendo em TypeScript – Interfaces.

Espero ter ajudado!
Até a próxima!