Propriedades dinâmicas de objetos em TypeScript: explicação para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como atribuir propriedades dinamicamente a um objeto em TypeScript? Explicação clara para iniciantes

\n\n

Olá, amigo! Se você já programou em JavaScript e depois migrou para TypeScript, certamente já enfrentou a situação de precisar adicionar uma nova propriedade a um objeto em tempo real. Em JS, isso se faz em dois segundos: obj.newProp = 'value'. Mas quando você tenta o mesmo em TypeScript, o compilador começa a reclamar: "Property 'newProp' does not exist on type ...". Familiar?

\n\n

Não se preocupe, isso é normal. TypeScript nos protege de erros acidentais, mas às vezes seu rigor parece excessivo. Neste artigo, vamos analisar como atribuir propriedades dinamicamente a objetos de forma correta e segura. Você aprenderá várias maneiras comprovadas — desde as simples até as mais elegantes. Vamos lá!

\n\n

Por que o TypeScript reclama?

\n\n

Antes de resolver o problema, vamos entender sua raiz. TypeScript é uma extensão do JavaScript que adiciona tipagem estática. Quando você declara um objeto:

\n\n
const user = { name: 'Ana', age: 25 };\n
\n\n

TypeScript infere automaticamente seu tipo: { name: string; age: number }. Isso significa que o objeto user pode conter apenas essas duas propriedades. Tentar adicionar email causará um erro de compilação:

\n\n
user.email = 'ana@exemplo.com'; // ❌ Erro!\n
\n\n

TypeScript não sabe que tal propriedade pode aparecer e bloqueia o código. Mas na vida real, muitas vezes precisamos adicionar propriedades dinamicamente — por exemplo, ao trabalhar com dados de APIs ou formulários. Vamos ver como fazer isso corretamente.

\n\n

Método 1: O mais simples — as any

\n\n

Uma maneira rápida, mas suja, é usar as any. Ele literalmente diz ao TypeScript: "Desative a verificação de tipos para este objeto".

\n\n
const user: any = { name: 'Ana', age: 25 };\nuser.email = 'ana@exemplo.com'; // ✅ Funciona\nuser.isAdmin = true;             // ✅ Funciona\n
\n\n

Por que isso é ruim? Porque você perde todas as vantagens do TypeScript: autocompletar, verificação de tipos, proteção contra erros de digitação. Se você escrever acidentalmente user.emial, não haverá erro — você só descobrirá em tempo de execução. Use este método apenas para prototipagem rápida ou quando souber exatamente o que está fazendo.

\n\n

Método 2: Assinatura de índice (Index Signature)

\n\n

Uma abordagem mais correta é declarar antecipadamente que o objeto pode conter propriedades dinâmicas. Para isso, usamos a assinatura de índice.

\n\n
interface User {\n  name: string;\n  age: number;\n  [key: string]: any; // 👈 Permite quaisquer propriedades adicionais\n}\n\nconst user: User = { name: 'Ana', age: 25 };\nuser.email = 'ana@exemplo.com'; // ✅ Funciona\nuser.phone = '+55-11-99999-9999'; // ✅ Funciona\n
\n\n

O que está acontecendo aqui? A notação [key: string]: any significa: "o objeto pode ter quaisquer chaves de string, e seus valores podem ser de qualquer tipo". Agora você pode adicionar propriedades dinamicamente, e o TypeScript não reclamará.

\n\n

Observação importante: se você quiser limitar os tipos de valores, substitua any por um tipo específico:

\n\n
interface User {\n  name: string;\n  age: number;\n  [key: string]: string | number; // Apenas strings e números\n}\n
\n\n

A assinatura de índice é uma excelente escolha quando você sabe antecipadamente que o objeto será expandido. Mas tenha cuidado: se a interface tiver outras propriedades com tipos diferentes, elas também devem corresponder à assinatura.

\n\n

Método 3: Tipo utilitário Record

\n\n

Se você precisar criar um objeto onde todas as chaves e valores são de um mesmo tipo, use o tipo embutido Record<Keys, Type>. Ele é ideal para dicionários ou mapeamentos.

\n\n
type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;\n\nconst roles: UserRoles = {\n  ana: 'admin',\n  joao: 'user',\n};\                

Blogs

Book Recommendations