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ê.