Conjunto indefinido e preenchimento de parâmetros em TypeScript
Conjunto indefinido de parâmetros
Se for necessário que uma função aceite um conjunto de parâmetros do mesmo tipo, utiliza-se o sinal de reticências, após o qual vem um array:
function addNumbers(firstNumber: number, ...numberArray: number[]): number {
let result = firstNumber;
for (let i = 0; i < numberArray.length; i++) {
result += numberArray[i];
}
return result;
}
let num1 = addNumbers(3, 7, 8);
console.log(num1); // 18
let num2 = addNumbers(3, 7, 8, 9, 4);
console.log(num2); // 31
Neste caso, a função addNumbers
possui fixamente apenas um parâmetro, o firstNumber
; os demais parâmetros são opcionais e são passados através do array numberArray
. Como esse array representa o tipo number[]
, que é um array de números, ao chamar a função podemos passar um conjunto indefinido de valores que devem ser do tipo number
.
Preenchimento de parâmetros
O TypeScript permite usar arrays para passar dados a vários parâmetros de uma só vez. Considere o seguinte exemplo:
function sum(...args: number[]): number {
let result = 0;
for (let i = 0; i < args.length; i++) {
result += args[i];
}
return result;
}
const numbers = [1, 3, 5, 7, 9];
let num = sum(...numbers);
console.log(num); // 25
Aqui, a função sum()
aceita um conjunto de parâmetros opcionais através do array args
. Pode haver um número indefinido desses parâmetros: zero, um, dois, três...
Para passar valores a esses parâmetros, é usado o operador ...
, após o qual é especificado o array de valores:
let num = sum(...numbers);
Ou seja, isso é equivalente a:
let num = sum(1, 3, 5, 7, 9);
Agora, vamos considerar uma função com um conjunto fixo de parâmetros:
function sum(a: number, b: number): number {
return a + b;
}
const numbers = [1, 3, 5, 7, 9];
let num = sum(...numbers); // ! Erro: a função sum aceita apenas dois parâmetros
console.log(num); // 25
Ao compilar este código, obteremos um erro, pois a função sum()
agora define claramente dois parâmetros. No entanto, ao chamá-la, estão sendo passados cinco valores: [1, 3, 5, 7, 9]
. Neste caso, precisamos passar um array que tenha tantos elementos quantos a função define parâmetros obrigatórios:
function sum(a: number, b: number): number {
return a + b;
}
const numbers = [1, 3] as const;
let num = sum(...numbers);
console.log(num); // 25
Observe que para o array é usada a expressão as const
:
const numbers = [1, 3] as const;
Isso é necessário para que o TypeScript saiba que o array não deve ser modificado e que ele deve ser tratado como um conjunto fixo de valores. Se não usarmos a palavra-chave const
, o TypeScript considerará que o array pode ser modificado e, portanto, não permitirá que ele seja passado como argumento para a função.
Se a função tiver parâmetros opcionais, o array de valores passado pode conter valores para eles ou não:
function sum(a: number, b: number, c?: number): number {
let result = a + b;
if (c !== undefined) {
result += c;
}
return result;
}
const numbers1 = [1, 3] as const;
let num1 = sum(...numbers1); // a = 1, b = 3
console.log(num1); // 4
const numbers2 = [1, 3, 7] as const;
let num2 = sum(...numbers2); // a = 1, b = 3, c = 7
console.log(num2); // 11
Além disso, podemos passar valores de diferentes tipos na forma de uma tupla:
function printValues(name: string, age: number) {
console.log(name);
console.log(age);
}
const values = ["Tom", 36] as const;
printValues(...values); // name = "Tom", age = 36
Neste caso, a função printValues()
aceita como primeiro valor um dado do tipo string
, e como segundo um valor do tipo number
. O array values
também representa um conjunto de valores desses tipos: ["Tom", 36]
. Como resultado, o primeiro valor da tupla values
é associado ao primeiro parâmetro da função, e o segundo valor ao segundo parâmetro. É importante que os valores passados correspondam em tipos aos parâmetros por posição. Por exemplo, no caso a seguir, obteremos um erro:
const values = [36, "Tom"] as const;
printValues(...values);
Como o primeiro valor do array values é do tipo number
, e o primeiro parâmetro da função é do tipo string
, obtemos uma incompatibilidade de tipos.