Introdução: por que TypeScript é um must-have para o desenvolvedor moderno
O TypeScript consolidou-se como o padrão de facto no desenvolvimento enterprise. De acordo com pesquisas do Stack Overflow, mais de 70% dos desenvolvedores frontend usam ou planejam usar TypeScript. Nas entrevistas, as perguntas sobre essa tecnologia são inevitáveis — mesmo que a vaga seja formalmente listada como "JavaScript Developer".
Neste artigo, abordaremos os tópicos principais que certamente serão perguntados em uma entrevista técnica: desde tipos básicos até generics complexos e tipos condicionais. O material é organizado do simples ao complexo, para que você possa se preparar de forma sistemática.
1. Base: tipos, interfaces e suas diferenças
1.1. Tipos primitivos e especiais
Vamos começar com o básico. O entrevistador quase certamente perguntará sobre any, unknown, never e void.
any— desativa a verificação de tipos. Usado apenas como último recurso durante migrações.unknown— alternativa segura ao any. Exige verificação de tipo antes do uso.never— tipo que nunca ocorre (funções que lançam exceções ou loops infinitos).void— ausência de valor de retorno em uma função.
function throwError(msg: string): never { throw new Error(msg);}
function log(msg: string): void { console.log(msg);}
let data: unknown = JSON.parse('{"name":"John"}');// data.name // Erro! É necessária verificaçãoif (typeof data === 'object' && data !== null) { console.log((data as Record<string, unknown>).name);}1.2. Interface vs Type: qual escolher?
Esta é uma pergunta clássica. Ambas as abordagens permitem descrever a estrutura de um objeto, mas há nuances:
- Interface — extensível (
extends), pode ser mesclada (declaration merging). - Type — pode descrever tipos union, intersection e primitivos. Não permite declaration merging.
// Interface - extensãointerface User { name: string;}interface User { age: number; // declaration merging}const user: User = { name: 'Alice', age: 30 };
// Type - uniontype Status = 'active' | 'inactive';type UserOrStatus = User | Status;Dica: Para objetos e classes, use interface; para composições complexas, use type.
2. Generics e tipos utilitários
2.1. Generics: programação genérica
Nenhuma entrevista séria fica sem generics. Saber escrever um tipo que se adapta ao argumento passado é um sinal de maturidade do desenvolvedor.
// Generic simplesfunction identity<T>(arg: T): T { return arg;}
// Restrição de genericfunction getLength<T extends { length: number }>(arg: T): number { return arg.length;}
// Generic para arrayfunction last<T>(arr: T[]): T | undefined { return arr[arr.length - 1];}Frequentemente perguntam sobre infer — a palavra-chave para inferir tipos dentro de construções condicionais:
// Extrai o tipo do elemento de uma Promisetype Unwrap<T> = T extends Promise<infer U> ? U : T;type Result = Unwrap<Promise<number>>; // number2.2. Tipos utilitários (Utility Types)
Conhecer os utilitários embutidos é o mínimo obrigatório. O entrevistador pode pedir para implementar um equivalente manualmente.
Partial<T>— todos os campos se tornam opcionais.Required<T>— todos os campos se tornam obrigatórios.Pick<T, K>— seleciona apenas as chaves especificadas.Omit<T, K>— om