Constantes em classes TypeScript: do iniciante ao profissional
\n\nVocê já escreveu em TypeScript e de repente percebeu: "Esta string mágica 'ADMIN' estou usando em dez lugares, e se eu digitar errado — o compilador fica em silêncio"? Dor familiar. Ou, pior ainda, alguém da equipe altera o valor da constante diretamente em tempo de execução, e você passa uma hora depurando para entender por que tudo quebrou.
\n\nBem-vindo ao mundo das constantes de classe em TypeScript. Isso não é apenas açúcar sintático — é a base de uma arquitetura limpa, previsível e segura. Neste artigo, vamos abordar todas as formas de declarar constantes em classes TypeScript: desde o simples readonly até técnicas avançadas com as const e genéricos. Vamos lá!
Por que constantes em classes são importantes?
\n\nImagine que você está desenvolvendo um aplicativo para uma loja online. Você tem uma classe Order e nela existem status: "pending", "shipped", "delivered". Se você espalhar essas strings por todo o código, mais cedo ou mais tarde alguém escreverá "PENDING" com letra maiúscula — e o bug está garantido. Constantes de classe TypeScript resolvem esse problema de uma vez por todas.
- \n
- Segurança de tipos: o compilador não permitirá passar "pendingg" onde é necessário "pending". \n
- Legibilidade:
OrderStatus.Pendingé mais claro do que apenas uma string. \n - Manutenção: alterar o valor em um lugar o altera em todos os lugares. \n
Método nº1: readonly — o básico, mas com nuances
\n\nA maneira mais simples é usar o modificador readonly. Ele proíbe a alteração do campo após a inicialização.
class AppConfig {\n readonly API_URL: string = 'https://api.example.com';\n readonly MAX_RETRIES: number = 3;\n}\n\nconst config = new AppConfig();\nconsole.log(config.API_URL); // 'https://api.example.com'\n// config.API_URL = 'new-url'; // Erro! Cannot assign to 'API_URL' because it is a read-only property.\n\nMas há um problema: readonly funciona apenas no nível do TypeScript. No JavaScript compilado, esses campos ainda podem ser alterados. Para proteção total, use Object.freeze ou # (campos privados).
Método nº2: static readonly — o rei das constantes
\n\nSe a constante não estiver vinculada a uma instância específica da classe (e isso acontece em 99% dos casos), use static readonly. Este é o padrão clássico de class constant typescript.
class MathConstants {\n static readonly PI: number = 3.14159;\n static readonly E: number = 2.71828;\n static readonly GOLDEN_RATIO: number = 1.61803;\n}\n\n// Acesso sem criar uma instância\nconsole.log(MathConstants.PI); // 3.14159\n// MathConstants.PI = 3.14; // Erro!\n\nEsta abordagem é ideal para configurações, constantes matemáticas, status e quaisquer valores que não devam mudar.
\n\nMétodo nº3: enum — quando há muitas constantes
\n\nSe você tem um grupo de constantes relacionadas (por exemplo, status de pedido), enum é seu melhor amigo. Ele cria um conjunto nomeado de valores.
enum OrderStatus {\n Pending = 'pending',\n Shipped = 'shipped',\n Delivered = 'delivered',\n Cancelled = 'cancelled'\n}\n\nclass Order {\n constructor(public status: OrderStatus) {}\n}\n\nconst order = new Order(OrderStatus.Pending);\nconsole.log(order.status); // 'pending'\n\n// order.status = 'pendingg'; // Erro! Type '"pendingg"' is not assignable to type 'OrderStatus'\n\nDica: se você usar enums de string (como no exemplo), eles fornecem valores legíveis em tempo de execução. enums numéricos são mais rápidos, mas mais difíceis de depurar.
Método nº4: as const — para máxima rigidez
\n\nÀs vezes, você quer que um objeto ou array se torne cons