TypeScript

Dominando Arrays, Tuplas e Enums em TypeScript na Prática em Projetos Reais

12 min de leitura

Dominando Arrays, Tuplas e Enums em TypeScript na Prática em Projetos Reais

Arrays em TypeScript: Fundamentos e Aplicações Práticas Arrays são um dos tipos de dados mais fundamentais na programação. Em TypeScript, eles vão além da sintaxe simples do JavaScript porque permitem definir o tipo exato de elementos que você armazenará, oferecendo segurança de tipo e melhor intellisense na IDE. Um array em TypeScript é uma coleção ordenada de elementos do mesmo tipo. Você pode declará-lo de duas formas principais: usando a notação com colchetes ( ) ou usando o genérico . A diferença é apenas sintática; ambas são equivalentes. Os métodos de array como , e são essenciais no dia a dia. Quando usados com tipagem correta, eles previnem bugs silenciosos. Observe como o TypeScript verifica os tipos nos callbacks: Idade média: ${idadeTotal / usuarios.length} Arrays Multidimensionais Às vezes você precisa de estruturas mais complexas, como matrizes. A sintaxe é simples, mas a tipagem deve ser clara para evitar confusões: --- Tuplas: Quando a Ordem e o Tipo Importam Tuplas são

<h2>Arrays em TypeScript: Fundamentos e Aplicações Práticas</h2>

<p>Arrays são um dos tipos de dados mais fundamentais na programação. Em TypeScript, eles vão além da sintaxe simples do JavaScript porque permitem definir o tipo exato de elementos que você armazenará, oferecendo segurança de tipo e melhor intellisense na IDE.</p>

<p>Um array em TypeScript é uma coleção ordenada de elementos do mesmo tipo. Você pode declará-lo de duas formas principais: usando a notação com colchetes (<code>tipo[]</code>) ou usando o genérico <code>Array&lt;tipo&gt;</code>. A diferença é apenas sintática; ambas são equivalentes.</p>

<pre><code class="language-typescript">// Duas formas de declarar arrays - ambas válidas

const numeros: number[] = [1, 2, 3, 4, 5];

const nomes: Array&lt;string&gt; = [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Carlos&quot;];

// TypeScript infere o tipo automaticamente

const mistos = [1, &quot;dois&quot;, true]; // any[] (evite isso)

// Solução melhor: seja explícito

const dados: (number | string)[] = [1, &quot;dois&quot;, 3, &quot;quatro&quot;];</code></pre>

<p>Os métodos de array como <code>map</code>, <code>filter</code> e <code>reduce</code> são essenciais no dia a dia. Quando usados com tipagem correta, eles previnem bugs silenciosos. Observe como o TypeScript verifica os tipos nos callbacks:</p>

<pre><code class="language-typescript">interface Usuario {

id: number;

nome: string;

idade: number;

}

const usuarios: Usuario[] = [

{ id: 1, nome: &quot;Ana&quot;, idade: 28 },

{ id: 2, nome: &quot;Bruno&quot;, idade: 35 },

{ id: 3, nome: &quot;Camila&quot;, idade: 22 }

];

// map com tipagem correta

const nomesMaiusculos = usuarios.map(usuario =&gt; usuario.nome.toUpperCase());

// Resultado: [&quot;ANA&quot;, &quot;BRUNO&quot;, &quot;CAMILA&quot;]

// filter com lógica de negócio

const maioresDeIdade = usuarios.filter(usuario =&gt; usuario.idade &gt;= 18);

// reduce para agregação

const idadeTotal = usuarios.reduce((soma, usuario) =&gt; soma + usuario.idade, 0);

console.log(Idade média: ${idadeTotal / usuarios.length}); // 28.33</code></pre>

<h3>Arrays Multidimensionais</h3>

<p>Às vezes você precisa de estruturas mais complexas, como matrizes. A sintaxe é simples, mas a tipagem deve ser clara para evitar confusões:</p>

<pre><code class="language-typescript">// Matriz 2D simples

const matriz: number[][] = [

[1, 2, 3],

[4, 5, 6],

[7, 8, 9]

];

// Acessando elementos

console.log(matriz[1][2]); // 6

// Array de objetos aninhados

interface Produto {

id: number;

nome: string;

preços: number[];

}

const catalogo: Produto[] = [

{ id: 1, nome: &quot;Notebook&quot;, preços: [2500, 2400, 2300] },

{ id: 2, nome: &quot;Mouse&quot;, preços: [50, 45, 40] }

];

// Acessar preço histórico

const ultimoPreço = catalogo[0].preços[catalogo[0].preços.length - 1];</code></pre>

<p>---</p>

<h2>Tuplas: Quando a Ordem e o Tipo Importam</h2>

<p>Tuplas são arrays com comprimento fixo e tipos específicos para cada posição. Elas são perfeitas quando você retorna múltiplos valores de uma função ou precisa garantir uma estrutura rígida.</p>

<p>A diferença fundamental entre um array e uma tupla é que a tupla não permite adicionar ou remover elementos além do que foi definido. Isso torna o código mais seguro e autodocumentado, pois qualquer pessoa lendo o tipo sabe exatamente quantas e quais informações esperar.</p>

<pre><code class="language-typescript">// Tupla básica: [nome, idade]

type Pessoa = [string, number];

const joao: Pessoa = [&quot;João&quot;, 30];

const maria: Pessoa = [&quot;Maria&quot;, 28];

// Erro de compilação - TypeScript previne

// const invalido: Pessoa = [&quot;Pedro&quot;]; // Falta um elemento

// const invalido: Pessoa = [&quot;Pedro&quot;, 25, &quot;extra&quot;]; // Elemento extra

// Usando tuplas em funções

function criarUsuario(nome: string, email: string): [string, string, boolean] {

return [nome, email, true];

}

const [nomeUsuario, emailUsuario, ativo] = criarUsuario(&quot;Alice&quot;, &quot;alice@email.com&quot;);

console.log(${nomeUsuario} - ${emailUsuario} - Ativo: ${ativo});</code></pre>

<h3>Tuplas Etiquetadas e Opcionais</h3>

<p>TypeScript permite etiquetar cada posição da tupla, tornando o código muito mais legível. Você também pode marcar elementos como opcionais com o operador <code>?</code>:</p>

<pre><code class="language-typescript">// Tupla etiquetada - nomes descritivos para cada posição

type APIResponse = [status: number, dados: string, timestamp: Date];

const resposta: APIResponse = [200, &#039;{&quot;id&quot;: 1}&#039;, new Date()];

console.log(Status: ${resposta[0]}); // Status: 200

// Elementos opcionais - útil para retornos variáveis

type ResultadoOperacao = [sucesso: boolean, mensagem?: string, erro?: Error];

const sucesso: ResultadoOperacao = [true];

const falha: ResultadoOperacao = [false, &quot;Operação falhou&quot;, new Error(&quot;Banco de dados indisponível&quot;)];

// Tupla com comprimento mínimo

type ListaComResto = [primeiro: string, segundo: string, ...resto: number[]];

const exemplo: ListaComResto = [&quot;a&quot;, &quot;b&quot;, 1, 2, 3, 4];</code></pre>

<h3>Tuplas em Casos Reais</h3>

<p>Tuplas brilham quando você precisa retornar múltiplos valores correlacionados. Veja um exemplo prático de uma função que processa um upload:</p>

<pre><code class="language-typescript">interface ArquivoUpload {

nome: string;

tamanho: number;

tipo: string;

}

function processarUpload(arquivo: ArquivoUpload):

[sucesso: boolean, caminhoOuErro: string, tamanhoEmMB?: number]

{

if (arquivo.tamanho &gt; 10 1024 1024) {

return [false, &quot;Arquivo excede 10MB&quot;];

}

if (![&quot;image/jpeg&quot;, &quot;image/png&quot;].includes(arquivo.tipo)) {

return [false, &quot;Tipo de arquivo não permitido&quot;];

}

const tamanhoEmMB = arquivo.tamanho / (1024 * 1024);

return [true, /uploads/${arquivo.nome}, tamanhoEmMB];

}

// Usando a tupla retornada

const [ok, info, mb] = processarUpload({

nome: &quot;foto.jpg&quot;,

tamanho: 5 1024 1024,

tipo: &quot;image/jpeg&quot;

});

if (ok) {

console.log(Upload bem-sucedido: ${info} (${mb?.toFixed(2)}MB));

} else {

console.log(Erro: ${info});

}</code></pre>

<p>---</p>

<h2>Enums: Valores Nomeados e Segurança de Tipo</h2>

<p>Enums (enumerações) permitem definir um conjunto de constantes nomeadas. Em vez de usar strings ou números mágicos espalhados pelo código, você define uma enum uma vez e a reutiliza. Isso torna o código mais seguro, mantível e legível.</p>

<p>TypeScript oferece dois tipos de enums: numéricos e de string. Cada um tem seus casos de uso ideais. Enums numéricos são compilados para constantes simples, enquanto enums de string são mais verbosos mas oferecem melhor legibilidade.</p>

<pre><code class="language-typescript">// Enum numérico - valores são atribuídos automaticamente (0, 1, 2...)

enum Status {

Pendente, // 0

Aprovado, // 1

Rejeitado // 2

}

let statusPedido: Status = Status.Pendente;

console.log(statusPedido); // 0

// Enum de string - mais legível e explícito

enum Role {

Admin = &quot;ADMIN&quot;,

Editor = &quot;EDITOR&quot;,

Viewer = &quot;VIEWER&quot;

}

let permissaUsuario: Role = Role.Editor;

console.log(permissaUsuario); // &quot;EDITOR&quot;

// Verificar tipo

if (permissaUsuario === Role.Editor) {

console.log(&quot;Acesso de editor concedido&quot;);

}</code></pre>

<h3>Enums na Prática: Aplicações em Código Real</h3>

<p>Enums são indispensáveis quando você precisa de um conjunto fechado de opções. Evitam strings espalhadas pela codebase e facilitam refatoração:</p>

<pre><code class="language-typescript">enum TipoPagamento {

Credito = &quot;CREDITO&quot;,

Debito = &quot;DEBITO&quot;,

Pix = &quot;PIX&quot;,

Boleto = &quot;BOLETO&quot;

}

enum StatusPedido {

Cancelado = &quot;CANCELADO&quot;,

AguardandoPagamento = &quot;AGUARDANDO_PAGAMENTO&quot;,

Processando = &quot;PROCESSANDO&quot;,

Entregue = &quot;ENTREGUE&quot;

}

interface Pedido {

id: number;

tipoPagamento: TipoPagamento;

status: StatusPedido;

valor: number;

}

function processarPagamento(pedido: Pedido): boolean {

switch (pedido.tipoPagamento) {

case TipoPagamento.Credito:

console.log(&quot;Processando cartão de crédito...&quot;);

return true;

case TipoPagamento.Pix:

console.log(&quot;Gerando QR Code PIX...&quot;);

return true;

case TipoPagamento.Boleto:

console.log(&quot;Emitindo boleto...&quot;);

return true;

case TipoPagamento.Debito:

console.log(&quot;Processando débito...&quot;);

return true;

default:

// TypeScript garante que todos os casos foram cobertos

const _nunca: never = pedido.tipoPagamento;

return false;

}

}

// Usando a enum

const meuPedido: Pedido = {

id: 123,

tipoPagamento: TipoPagamento.Pix,

status: StatusPedido.AguardandoPagamento,

valor: 199.90

};

processarPagamento(meuPedido);</code></pre>

<h3>Enums Heterogêneos e Reverse Mapping</h3>

<p>TypeScript permite enums com valores mistos (números e strings), embora isso não seja recomendado. Mais útil é conhecer o reverse mapping automático em enums numéricos:</p>

<pre><code class="language-typescript">// Reverse mapping - acesso bidirecional

enum Direcao {

Cima = 0,

Direita = 1,

Baixo = 2,

Esquerda = 3

}

console.log(Direcao.Cima); // 0

console.log(Direcao[0]); // &quot;Cima&quot;

console.log(Direcao[Direcao.Cima]); // &quot;Cima&quot;

// Útil para debug ou quando você recebe um valor numérico da API

function obterDescricaoDirecao(dir: number): string {

return Direcao[dir]; // Retorna o nome da direção

}

console.log(obterDescricaoDirecao(2)); // &quot;Baixo&quot;</code></pre>

<p>---</p>

<h2>Combinando Arrays, Tuplas e Enums: Um Projeto Completo</h2>

<p>Na prática, esses três conceitos trabalham juntos. Veja um exemplo realista de um sistema de carrinhos de compra:</p>

<pre><code class="language-typescript">// Definir tipos com enum e tupla

enum TamanhoUm {

PP = &quot;PP&quot;,

P = &quot;P&quot;,

M = &quot;M&quot;,

G = &quot;G&quot;,

GG = &quot;GG&quot;

}

enum StatusCarrinho {

Vazio = &quot;VAZIO&quot;,

Preenchido = &quot;PREENCHIDO&quot;,

Finalizado = &quot;FINALIZADO&quot;

}

type ItemCarrinho = [id: number, quantidade: number, preco: number];

interface Produto {

id: number;

nome: string;

tamanho: TamanhoUm;

}

interface Carrinho {

usuario_id: number;

status: StatusCarrinho;

itens: ItemCarrinho[];

dataCriacao: Date;

}

// Funções que usam tudo junto

function adicionarAoCarrinho(

carrinho: Carrinho,

produto: Produto,

quantidade: number,

preco: number

): Carrinho {

const novoItem: ItemCarrinho = [produto.id, quantidade, preco];

return {

...carrinho,

itens: [...carrinho.itens, novoItem],

status: StatusCarrinho.Preenchido

};

}

function calcularTotal(carrinho: Carrinho): number {

return carrinho.itens.reduce((total, [_, quantidade, preco]) =&gt; {

return total + (quantidade * preco);

}, 0);

}

function obterResumoCarrinho(carrinho: Carrinho): [status: string, total: number, quantidade: number] {

const total = calcularTotal(carrinho);

const quantidade = carrinho.itens.reduce((acc, [_, qtd]) =&gt; acc + qtd, 0);

return [StatusCarrinho[carrinho.status], total, quantidade];

}

// Usando tudo junto

const meuCarrinho: Carrinho = {

usuario_id: 1,

status: StatusCarrinho.Vazio,

itens: [],

dataCriacao: new Date()

};

const produto1: Produto = { id: 1, nome: &quot;Camiseta&quot;, tamanho: TamanhoUm.M };

const carrinhoAtualizado = adicionarAoCarrinho(meuCarrinho, produto1, 2, 89.90);

const [status, total, quantidade] = obterResumoCarrinho(carrinhoAtualizado);

console.log(Status: ${status}, Total: R$ ${total.toFixed(2)}, Itens: ${quantidade});

// Saída: Status: PREENCHIDO, Total: R$ 179.80, Itens: 2</code></pre>

<p>Este exemplo mostra como enums fornecem valores seguros, tuplas garantem estrutura de dados e arrays armazenam coleções de forma tipada e eficiente.</p>

<p>---</p>

<h2>Conclusão</h2>

<p>Você aprendeu três pilares fundamentais do TypeScript: <strong>Arrays</strong> oferecem coleções flexíveis e tipadas com métodos poderosos; <strong>Tuplas</strong> garantem estruturas rígidas quando você retorna múltiplos valores ou precisa de uma forma específica; e <strong>Enums</strong> eliminam valores mágicos (strings e números soltos) fornecendo constantes nomeadas e seguras.</p>

<p>O verdadeiro poder está em combinar esses três conceitos. Use arrays para coleções de tamanho variável, tuplas para retornos de múltiplos valores com tipos específicos por posição, e enums para representar estados e valores finitos. Essa combinação não apenas torna seu código mais seguro (TypeScript detectará erros em tempo de compilação), mas também torna muito mais fácil para outros desenvolvedores entender sua intenção.</p>

<p>---</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types" target="_blank" rel="noopener noreferrer">TypeScript Handbook - Arrays and Tuples</a></li>

<li><a href="https://www.typescriptlang.org/docs/handbook/enum.html" target="_blank" rel="noopener noreferrer">TypeScript Handbook - Enums</a></li>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" target="_blank" rel="noopener noreferrer">MDN Web Docs - Array Methods</a></li>

<li><a href="https://basarat.gitbook.io/typescript/type-system" target="_blank" rel="noopener noreferrer">TypeScript Deep Dive - Chapter on Types</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em TypeScript

Dominando Classes em TypeScript: Modificadores, Readonly e Parameter Properties em Projetos Reais
Dominando Classes em TypeScript: Modificadores, Readonly e Parameter Properties em Projetos Reais

Introdução aos Modificadores de Acesso em TypeScript Os modificadores de aces...

O que Todo Dev Deve Saber sobre Domain-Driven Design com TypeScript: Entidades e Value Objects Tipados
O que Todo Dev Deve Saber sobre Domain-Driven Design com TypeScript: Entidades e Value Objects Tipados

Fundamentos do Domain-Driven Design Domain-Driven Design (DDD) é uma metodolo...

Componentes Genéricos em React com TypeScript: Do Básico ao Avançado
Componentes Genéricos em React com TypeScript: Do Básico ao Avançado

O que são Componentes Genéricos em React com TypeScript? Componentes genérico...