E aí, galera!
Resumindo e dando a resposta, que é um pouco contraintuitiva para quem vem de outras linguagens, não, não existe imutabilidade garantida no tempo de execução do JavaScript ou TypeScript. Mas o TypeScript nos oferece alguns caminhos para forçar essa prática e te avisar dos erros antes que teu código rode.
TL;DR:
Mas é algo interessante.
Vou te mostrar o motivo por trás disso e como usar o TypeScript para escrever um código muito mais seguro e fácil de entender.
A raiz do problema: JavaScript é mutável por natureza
O JavaScript foi construído com a ideia de mutabilidade para a maioria dos seus tipos de referência, como por exemplo, objetos e arrays.
Quando usamos const, a única coisa que garantimos é que a variável não será reatribuída. O conteúdo do objeto ou array que ela aponta na memória pode ser alterado livremente:
const user = { name: "Fernando", languages: 5 };
// O objeto interno foi alterado, e o TS não reclama.
user.languages = 4;
Em projetos grandes, se você passa esse objeto para várias funções (em um componente React, por exemplo), qualquer função pode mudar ele sem aviso, gerando um side effect por exemplo. A imutabilidade é a prática de sempre criar uma nova cópia ao invés de alterar o original, mas o JavaScript não te obriga a isso.
A solução: TypeScript
O TypeScript atua como um sistema de tipos rodando em tempo de compilação. Ele usa isso para nos dar opções que obrigam a imutabilidade como uma regra, não como um recurso da linguagem.
O uso do modificador readonly
Essa é a forma mais simples de definir que a propriedade não pode mudar. Se alguém tentar, o compilador vai retornar erro:
interface Pedido {
readonly id: number; // <-- não poderia ser modificado
status: string;
}
const meuPedido: Pedido = { id: 22, status: "Pendente" };
meuPedido.id = 23; // erro de compilação que bloqueia rodar o código
Uso do utility type Readonly<T>
Se você quer que todas as propriedades de um tipo ou interface sejam imutáveis, você usa o Utility Type Readonly.
interface Settings {
darkMode: boolean;
language: string;
}
// transforma todas as chaves em 'readonly'
type ConfigApp = Readonly<Settings>;
config.darkMode = false; // vai retornar erro
as const
Para configurações e valores que nunca devem mudar, o as const é o ideal. Ele não só torna o objeto readonly, mas também transforma os valores em Tipos Literais. Isso significa que o valor do type é o próprio tipo.
Como por exemplo:
const ERROR_CODES = {
NOT_FOUND: 404,
SERVER_ERROR: 500,
UNAUTHORIZED: 401
} as const;
console.log("Objeto:", ERROR_CODES); // retorna o objeto acima
console.log("Tipo literal de not found:", ERROR_CODES.NOT_FOUND); // Tipo literal de not found: 404
console.log("Tipo literal de server error:", ERROR_CODES.SERVER_ERROR); // Tipo literal de server error: 500
Como conclusão, nós podemos afirmar que, basicamente imutabilidade no JS é mais uma prática.
O TS não faz seu JavaScript se comportar como Rust ou C++. O que o TypeScript garante é a consistência e a segurança dos seus dados em tempo de desenvolvimento, impedindo que esses bugs cheguem ao ambiente de execução.
Em sistemas de grande escala onde a mutabilidade pode ser um pesadelo, saber desses pontos pode ter dar previsibilidade.
Top comments (0)