TypeScript se tornou o padrĂŁo da indĂșstria para desenvolvimento web em grande escala. Embora a maioria dos desenvolvedores conheça o bĂĄsico de interfaces e tipos, o verdadeiro poder estĂĄ no seu sistema de tipos avançado. Aqui estĂŁo 5 padrĂ”es que irĂŁo distingui-lo como engenheiro sĂȘnior.
1. Generic Constraints
Generics sĂŁo poderosos, mas Ă s vezes vocĂȘ precisa limitar o que pode ser passado. extends Ă© seu aliado aqui.
interface HasId { id: string; } function getById<T extends HasId>(list: T[], id: string): T | undefined { return list.find((item) => item.id === id); }
Ao garantir que T estende HasId, garantimos que acessar .id dentro da função é seguro.
2. Conditional Types
Tipos condicionais permitem criar mapeamentos de tipos nĂŁo uniformes. A sintaxe Ă© semelhante ao operador ternĂĄrio em JavaScript.
type IsString<T> = T extends string ? true : false; type A = IsString<string>; // true type B = IsString<number>; // false
Um caso de uso prĂĄtico Ă© filtrar tipos de uma union:
type Diff<T, U> = T extends U ? never : T; type NonNullable<T> = Diff<T, null | undefined>;
3. Mapped Types
Mapped types permitem criar novos tipos baseados em tipos existentes, transformando propriedades.
type ReadOnly<T> = { readonly [P in keyof T]: T[P]; }; interface User { name: string; age: number; } type ReadOnlyUser = ReadOnly<User>;
VocĂȘ pode atĂ© adicionar ou remover modificadores:
type Mutable<T> = { -readonly [P in keyof T]: T[P]; };
4. Template Literal Types
Introduzidos no TypeScript 4.1, eles permitem manipular tipos de string diretamente.
type World = 'world'; type Greeting = `hello ${World}`; // "hello world" type Color = 'red' | 'blue'; type Quantity = 'light' | 'dark'; type Palette = `${Quantity}-${Color}`; // "light-red" | "light-blue" | "dark-red" | "dark-blue"
Isso Ă© incrivelmente Ăștil para tipar strings que seguem um padrĂŁo especĂfico, como classes CSS ou nomes de eventos.
5. A Palavra-chave infer
A palavra-chave infer dentro de tipos condicionais permite extrair tipos de outros tipos.
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; function check(): boolean { return true; } type CheckReturn = ReturnType<typeof check>; // boolean
Aqui, estamos pedindo ao TypeScript para "inferir" o tipo de retorno R de uma função e retornå-lo.
ConclusĂŁo
Dominar esses padrĂ”es permite escrever bibliotecas e utilitĂĄrios que sĂŁo robustos e proporcionam uma excelente experiĂȘncia para o desenvolvedor (DX). O objetivo do TypeScript avançado nĂŁo Ă© complexidade pela complexidade, mas sim segurança e expressividade.