Introdução: O mito da conversão de tipos "mágica"
\n\nTodo desenvolvedor TypeScript, mais cedo ou mais tarde, se depara com a seguinte situação: você recebe um JSON do servidor, tem certeza de que conhece sua estrutura e faz um simples cast usando as. E… nada funciona. Os métodos da classe estão ausentes, os campos estão undefined, e a depuração se transforma em uma missão.
A pergunta "How do I cast a JSON object to a TypeScript class?" é uma das mais populares no Stack Overflow (dezenas de milhares de visualizações). E não é surpresa. TypeScript é uma camada extra que existe apenas durante a compilação. Em tempo de execução, sua "classe" é apenas um objeto JavaScript simples.
\n\nNeste artigo, vamos analisar os 5 erros mais comuns e perigosos que os desenvolvedores cometem ao trabalhar com JSON e classes TypeScript. Você aprenderá como evitá-los e obterá soluções prontas para código em produção.
\n\nErro nº 1: Usar as para uma conversão "real"
\n\nA armadilha mais comum é pensar que a construção jsonData as MyClass cria uma instância da classe.
O que realmente acontece?
\nO operador as (ou a sintaxe de angle-bracket) é uma afirmação de tipo. Ele diz ao compilador: "Confie em mim, eu sei o tipo". Mas em JavaScript, ele não realiza nenhuma mágica.
class User {\n name: string = '';\n greet(): string {\n return `Olá, ${this.name}!`;\n }\n}\n\nconst rawData = JSON.parse('{"name": "Ana"}');\nconst user = rawData as User;\n\nconsole.log(user.name); // "Ana" — funciona\nconsole.log(user.greet()); // TypeError: user.greet is not a function\n\n\nPor quê? Porque rawData é um objeto comum { name: 'Ana' }. Ele não tem o protótipo User.prototype e, portanto, não tem o método greet.
Como corrigir?
\nSempre crie uma instância real da classe. A maneira básica é usar Object.assign:
const user = Object.assign(new User(), rawData);\nconsole.log(user.greet()); // "Olá, Ana!"\n\n\nMas este método tem nuances, que discutiremos a seguir.
\n\nErro nº 2: Ignorar objetos e arrays aninhados
\n\nVocê usa Object.assign felizmente, mas seus dados contêm estruturas aninhadas. E aí começa o inferno.
class Address {\n city: string = '';\n zip: string = '';\n}\n\nclass Company {\n name: string = '';\n address: Address = new Address();\n}\n\nconst data = JSON.parse('{"name": "TechCorp", "address": {"city": "Moscou", "zip": "101000"}}');\nconst company = Object.assign(new Company(), data);\n\nconsole.log(company.address.city); // "Moscou" — sorte?\nconsole.log(company.address instanceof Address); // false!\n\n\nProblema: address permaneceu um objeto simples, não uma instância de Address. Se Address tiver métodos ou propriedades computadas, eles serão perdidos.
Solução: Conversão recursiva
\nEscreva uma função fábrica ou use a biblioteca class-transformer:
import { plainToClass } from 'class-transformer';\n\nconst company = plainToClass(Company, data);\nconsole.log(company.address instanceof Address); // true\n\n\nclass-transformer percorre recursivamente todos os campos e cria as instâncias corretas das classes com base nos decoradores @Type.
Erro nº 3: Perda de valores padrão
\n\nTypeScript permite definir valores padrão para campos diretamente na classe. Mas ao "converter" JSON, esses valores podem ser sobrescritos por undefined.
class Config {\n theme: string = 'light';\n fontSize: number = 14;\n language: string = 'pt';\n}\n\nconst partialData = JSON.parse('{"theme": "dark"}');\nconst config = Object.assign(new Config(), partialData);\n\nconsole.l