Reflexão e Introspecção em TypeScript: como o código se observa

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

Reflexão e Introspecção em TypeScript: como o código se observa

\n\n

Imagine um programa capaz de analisar a si mesmo em tempo de execução. Ele pode descobrir quais tipos suas variáveis possuem, quais propriedades os objetos têm e até tomar decisões com base nessas informações. Parece mágica? Na verdade, isso é reflexão e introspecção — técnicas poderosas de metaprogramação que também estão disponíveis em TypeScript.

\n\n

Neste artigo, vamos entender a diferença entre reflexão e introspecção, como usá-las em TypeScript e por que isso pode ser útil em projetos reais. Nada de teoria chata — apenas código vivo e exemplos práticos.

\n\n

O que são Introspecção e Reflexão?

\n\n

Vamos logo esclarecer isso. Na programação, esses termos são frequentemente confundidos, mas há diferença:

\n\n
    \n
  • Introspecção — é a capacidade do programa de observar sua própria estrutura. Você pode descobrir quais propriedades um objeto tem, qual é o seu tipo, mas não pode alterá-las.
  • \n
  • Reflexão — é um nível mais avançado: o programa não apenas se observa, mas também altera seu comportamento em tempo de execução. Por exemplo, invoca métodos dinamicamente ou cria novas instâncias de classes.
  • \n
\n\n

Em JavaScript, no qual TypeScript é baseado, a reflexão é implementada através de Reflect e Proxy. Mas o TypeScript adiciona sua própria camada — a tipagem estática, que parcialmente "desaparece" na compilação. É aqui que a coisa fica interessante.

\n\n

Introspecção de tipos: type guards e typeof

\n\n

A maneira mais simples de olhar dentro do código é usar type guards. São construções que verificam o tipo de dado em tempo de execução:

\n\n
function isString(value: unknown): value is string {\n  return typeof value === 'string';\n}\n\nfunction processValue(value: unknown) {\n  if (isString(value)) {\n    // TypeScript sabe que value é uma string\n    console.log(value.toUpperCase());\n  } else {\n    console.log('Isso não é uma string');\n  }\n}
\n\n

Observe o value is string — isso é um predicado de tipo. Ele informa ao TypeScript que, após a verificação, a variável pertence a um tipo específico. Isso é introspecção pura: observamos o tipo, mas não o alteramos.

\n\n

Reflexão através da API Reflect

\n\n

O objeto Reflect é um mecanismo embutido de reflexão em JavaScript. Ele permite realizar ações que antes eram feitas por métodos "mágicos", mas agora são unificadas. Aqui estão alguns exemplos:

\n\n
const user = {\n  name: 'Alexey',\n  age: 30,\n};\n\n// Introspecção — obtém a lista de chaves\nconsole.log(Reflect.ownKeys(user)); // ['name', 'age']\n\n// Reflexão — lê dinamicamente uma propriedade\nconst propertyName = 'name';\nconsole.log(Reflect.get(user, propertyName)); // 'Alexey'\n\n// Reflexão — define dinamicamente uma propriedade\nReflect.set(user, 'name', 'Maria');\nconsole.log(user.name); // 'Maria'
\n\n

Por que Reflect é melhor que o velho user[prop]? Primeiro, ele retorna boolean para operações de definição, o que é útil para verificações. Segundo, ele funciona corretamente com proxies e descritores de propriedades. Para TypeScript, isso é especialmente importante, pois a reflexão permite contornar a tipagem estática quando realmente necessário.

\n\n

Decoradores: reflexão turbinada

\n\n

Decoradores são, talvez, o exemplo mais marcante de reflexão em TypeScript. Eles permitem anotar classes, métodos, propriedades e parâmetros, e então alterar seu comportamento. Desde o TypeScript 5.0, os decoradores se tornaram padrão (stage 3).

\n\n

Aqui está um exemplo de um decorador simples para registrar a chamada de um método:

\n\n
function logMethod(\n  target: any,\n  propertyKey: string,\n  descriptor: PropertyDescriptor\n) {\n  const originalMethod = descriptor.valu                

Blogs

Book Recommendations