10 Dicas para se Tornar um Melhor Programador TypeScript

TypeScript vai muito além de simples anotações de tipo no JavaScript. Seu verdadeiro potencial está na composição de tipos, inferência automática e manipulação avançada, permitindo que você escreva código mais seguro, legível e eficiente. Neste artigo, exploramos práticas recomendadas que podem elevar suas habilidades e tornar seu código TypeScript mais poderoso. 1. Pense em "Conjuntos" ao Trabalhar com Tipos Cada tipo em TypeScript pode ser visto como um conjunto de valores. Isso ajuda a entender operações como união (|) e interseção (&). *Exemplo: * type Dimensao = { altura: number; largura: number }; type Aparencia = { cor: string; opacidade: number }; type Janela = Dimensao & Aparencia; // { altura: number; largura: number; cor: string; opacidade: number } Aqui, & cria uma interseção, garantindo que Janela tenha todas as propriedades. Comparação: & Interseção: elementos comuns aos dois tipos `` União: elementos de ambos os tipos 2. Diferencie "Tipo Declarado" e "Tipo Reduzido" TypeScript ajusta automaticamente os tipos com base no fluxo do código. Exemplo: function processar(valor: string | boolean) { if (typeof valor === 'string') { console.log(valor.toUpperCase()); // OK, pois TypeScript reduz valor para string } } Isso evita a necessidade de conversões desnecessárias. 3. Prefira União Discriminada a Campos Opcionais Usar type com uma propriedade discriminatória melhora a segurança do código. Errado: type Veiculo = { tipo: 'carro' | 'moto'; portas?: number; cilindradas?: number; }; Correto: type Carro = { tipo: 'carro'; portas: number }; type Moto = { tipo: 'moto'; cilindradas: number }; type Veiculo = Carro | Moto; 4. Use "Type Predicate" para Evitar "Type Assertion" Usar um type predicate permite que o TypeScript compreenda automaticamente a especialização de tipos dentro de funções, evitando a necessidade de conversões explícitas (as). Isso melhora a segurança do código e reduz erros inesperados. Exemplo: function isCarro(veiculo: Veiculo): veiculo is Carro { return veiculo.tipo === 'carro'; } const veiculos: Veiculo[] = obterVeiculos(); const carros = veiculos.filter(isCarro); // TypeScript agora sabe que isso é um Carro[] Outro Exemplo: type Animal = { tipo: 'cachorro' | 'gato'; som?: string }; type Cachorro = { tipo: 'cachorro'; som: 'latido' }; type Gato = { tipo: 'gato'; som: 'miado' }; type Especie = Cachorro | Gato; function isCachorro(animal: Especie): animal is Cachorro { return animal.tipo === 'cachorro'; } const animais: Especie[] = [ { tipo: 'cachorro', som: 'latido' }, { tipo: 'gato', som: 'miado' } ]; const apenasCachorros = animais.filter(isCachorro); console.log(apenasCachorros); // [{ tipo: 'cachorro', som: 'latido' }] 5. Controle como Tipos de União São Distribuídos TypeScript distribui tipos em uniões automaticamente. Podemos alterar isso com colchetes: Exemplo: type ToList = [T] extends [Array] ? T : T[]; type Resultado = ToList; // Agora é (string | number)[] 6. Utilize "Exaustividade" em switch para Evitar Casos Não Tratados Usar never pode ajudar a garantir que todas as possibilidades sejam cobertas: function calcularDesconto(produto: Produto) { switch (produto.categoria) { case 'eletronico': return produto.preco * 0.9; case 'vestuario': return produto.preco * 0.8; default: const exaustivo: never = produto; throw new Error('Categoria desconhecida'); } } 7. Prefira type a interface Use type, a menos que precise de declaration merging ou de OO: type Cliente = { nome: string; idade: number; email: string }; 8. Use Tuplas ao Invés de Arrays Genéricos type Coordenada = [number, number, string]; const minhaLocalizacao: Coordenada = [40.7128, -74.0060, 'Nova York']; 9. Controle a Especificidade da Inferência de Tipos Use as const para restringir valores. Use satisfies para validar sem alterar inferência: const produto = { preco: 100, nome: 'Notebook' } satisfies { preco: number; nome?: string }; console.log(produto.nome.length); // Ok, pois TypeScript sabe que nome não é `undefined` **10. Evite Código Repetitivo com Manipulação de Tipos Exemplo: type Funcionario = { nome: string; cargo: string; salario: number }; type DadosSalariais = Pick; Isso elimina redundância ao criar novos tipos baseados em tipos existentes.

Mar 21, 2025 - 16:56
 0
10 Dicas para se Tornar um Melhor Programador TypeScript

TypeScript vai muito além de simples anotações de tipo no JavaScript. Seu verdadeiro potencial está na composição de tipos, inferência automática e manipulação avançada, permitindo que você escreva código mais seguro, legível e eficiente. Neste artigo, exploramos práticas recomendadas que podem elevar suas habilidades e tornar seu código TypeScript mais poderoso.

1. Pense em "Conjuntos" ao Trabalhar com Tipos

Cada tipo em TypeScript pode ser visto como um conjunto de valores. Isso ajuda a entender operações como união (|) e interseção (&).

*Exemplo: *

type Dimensao = { altura: number; largura: number };
type Aparencia = { cor: string; opacidade: number };
type Janela = Dimensao & Aparencia; // { altura: number; largura: number; cor: string; opacidade: number }

Aqui, & cria uma interseção, garantindo que Janela tenha todas as propriedades.
Comparação:

& Interseção: elementos comuns aos dois tipos
 `` União: elementos de ambos os tipos

2. Diferencie "Tipo Declarado" e "Tipo Reduzido"

TypeScript ajusta automaticamente os tipos com base no fluxo do código.

Exemplo:

function processar(valor: string | boolean) {
  if (typeof valor === 'string') {
    console.log(valor.toUpperCase()); // OK, pois TypeScript reduz valor para string
  }
}

Isso evita a necessidade de conversões desnecessárias.

3. Prefira União Discriminada a Campos Opcionais

Usar type com uma propriedade discriminatória melhora a segurança do código.

Errado:

type Veiculo = {
  tipo: 'carro' | 'moto';
  portas?: number;
  cilindradas?: number;
};

Correto:

type Carro = { tipo: 'carro'; portas: number };
type Moto = { tipo: 'moto'; cilindradas: number };
type Veiculo = Carro | Moto;

4. Use "Type Predicate" para Evitar "Type Assertion"
Usar um type predicate permite que o TypeScript compreenda automaticamente a especialização de tipos dentro de funções, evitando a necessidade de conversões explícitas (as). Isso melhora a segurança do código e reduz erros inesperados.

Exemplo:

function isCarro(veiculo: Veiculo): veiculo is Carro {
  return veiculo.tipo === 'carro';
}

const veiculos: Veiculo[] = obterVeiculos();
const carros = veiculos.filter(isCarro); // TypeScript agora sabe que isso é um Carro[]

Outro Exemplo:

type Animal = { tipo: 'cachorro' | 'gato'; som?: string };
type Cachorro = { tipo: 'cachorro'; som: 'latido' };
type Gato = { tipo: 'gato'; som: 'miado' };

type Especie = Cachorro | Gato;

function isCachorro(animal: Especie): animal is Cachorro {
  return animal.tipo === 'cachorro';
}

const animais: Especie[] = [
  { tipo: 'cachorro', som: 'latido' },
  { tipo: 'gato', som: 'miado' }
];

const apenasCachorros = animais.filter(isCachorro);
console.log(apenasCachorros); // [{ tipo: 'cachorro', som: 'latido' }]

5. Controle como Tipos de União São Distribuídos

TypeScript distribui tipos em uniões automaticamente. Podemos alterar isso com colchetes:

Exemplo:

type ToList = [T] extends [Array] ? T : T[];
type Resultado = ToList; // Agora é (string | number)[]

6. Utilize "Exaustividade" em switch para Evitar Casos Não Tratados

Usar never pode ajudar a garantir que todas as possibilidades sejam cobertas:

function calcularDesconto(produto: Produto) {
  switch (produto.categoria) {
    case 'eletronico':
      return produto.preco * 0.9;
    case 'vestuario':
      return produto.preco * 0.8;
    default:
      const exaustivo: never = produto;
      throw new Error('Categoria desconhecida');
  }
}

7. Prefira type a interface

Use type, a menos que precise de declaration merging ou de OO:

type Cliente = { nome: string; idade: number; email: string };

8. Use Tuplas ao Invés de Arrays Genéricos

type Coordenada = [number, number, string];
const minhaLocalizacao: Coordenada = [40.7128, -74.0060, 'Nova York'];

9. Controle a Especificidade da Inferência de Tipos

Use as const para restringir valores.
Use satisfies para validar sem alterar inferência:

const produto = { preco: 100, nome: 'Notebook' } satisfies { preco: number; nome?: string };
console.log(produto.nome.length); // Ok, pois TypeScript sabe que nome não é `undefined`

**10. Evite Código Repetitivo com Manipulação de Tipos

Exemplo:

type Funcionario = { nome: string; cargo: string; salario: number };
type DadosSalariais = Pick;

Isso elimina redundância ao criar novos tipos baseados em tipos existentes.