TypeScript tem uma curva de aprendizado, mas alguns padrões valem ouro uma vez que você os absorve.

Discriminated unions para estados

Em vez de múltiplos booleans (isLoading, isError, isSuccess), use uma union discriminada:

type RequestState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: string };

O TypeScript vai te obrigar a tratar cada caso no switch. Sem bugs de estado impossível.

Satisfies em vez de as

const config = {
  timeout: 3000,
  retries: 3,
} satisfies Partial<Config>;

satisfies valida o tipo sem perder a inferência precisa dos valores. as é silêncio forçado; satisfies é validação real.

Template literal types

type EventName = `on${Capitalize<string>}`;
// onCLick, onChange, onSubmit...

Útil para sistemas de eventos, chaves de i18n, nomes de rotas.

Takeaway

TypeScript não é sobre escrever mais — é sobre deixar o compilador trabalhar por você.