Interfaces Fluentes com Tipos
Encadeie métodos acompanhando o estado acumulado nos tipos.
Interfaces Fluentes com Tipos é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 4 aulas no total.
Acompanhando o que foi definido
Um construtor simples permite chamar build() a qualquer momento, até mesmo quando faltam campos obrigatórios. Podemos fazer melhor ao acompanhar o estado acumulado no sistema de tipos usando um parâmetro de tipo genérico.
Um parâmetro de tipo de estado
Fornecemos ao construtor um S genérico que registra quais chaves foram fornecidas até o momento. À medida que cada método é executado, ampliamos S para incluir uma nova chave.
class Builder<S> {
// S is a record of keys set so far, e.g. {} or { url: string }
private data: Record<string, unknown> = {};
}Cada método adiciona uma chave
Um método definidor devolve um novo construtor tipado cujo S inclui a chave recém-adicionada. Em tempo de execução, o valor é armazenado; o tipo é ampliado de acordo.
set<K extends string, V>(key: K, value: V): Builder<S & Record<K, V>> {
this.data[key] = value;
return this as unknown as Builder<S & Record<K, V>>;
}O truque da interseção
A expressão S & Record<K, V> faz a interseção do estado anterior com a nova chave. Depois de duas chamadas, o tipo conhece precisamente as duas chaves.
type Empty = {};
type AfterUrl = Empty & Record<"url", string>;
type AfterBoth = AfterUrl & Record<"method", string>;
// AfterBoth = { url: string; method: string }Um construtor fluente concreto
Aqui, um construtor de requisições transporta sua estrutura acumulada a cada chamada. O compilador sempre sabe exatamente quais campos existem.
class Req<S> {
private d: Record<string, unknown> = {};
url(u: string): Req<S & { url: string }> {
this.d.url = u; return this as any;
}
method(m: string): Req<S & { method: string }> {
this.d.method = m; return this as any;
}
}O tipo cresce à medida que encadeia chamadas
Cada chamada na cadeia produz um tipo de construtor mais específico. Ao passar o cursor sobre o resultado em um editor, é possível ver o estado acumulado.
const partial = new Req<{}>().url("/x");
// type: Req<{ url: string }>
const full = partial.method("POST");
// type: Req<{ url: string; method: string }>Por que acompanhar o estado?
Quando o tipo carrega o conjunto de chaves fornecidas, podemos restringir posteriormente build() para que seja compilado apenas quando as chaves obrigatórias estiverem presentes. O parâmetro de estado é a base dessa garantia.
Lendo a estrutura acumulada
É possível extrair a estrutura acumulada para inspecioná-la. Isso confirma que o tipo do construtor reflete exatamente o que foi configurado.
type StateOf<T> = T extends Req<infer S> ? S : never;
type S1 = StateOf<Req<{ url: string }>>; // { url: string }O tempo de execução permanece simples
Toda a complexidade está nos tipos. Em tempo de execução, cada método definidor apenas armazena um valor em um objeto. As conversões (as any) fazem a ponte entre o objeto em tempo de execução e o tipo mais rico usado em tempo de compilação.
const r = new Req<{}>().url("/users").method("GET");
console.log("configured url and method");Estado genérico como um registro
Pense em S como um registro do que foi definido. Os métodos acrescentam entradas; a etapa de build poderá ler o registro posteriormente para decidir se a construção é permitida.
Contrapartidas
O acompanhamento do estado no nível dos tipos fornece indicações precisas no ambiente de desenvolvimento e impede construções incompletas, ao custo de algumas conversões e de tipos genéricos mais avançados. Isso compensa em interfaces usadas por muitas pessoas.
Verificação rápida
Verificação rápida desta lição.
Recapitulação
Um construtor tipado fluente carrega um parâmetro de estado genérico S. Cada método definidor faz a interseção de S com a nova chave (S & Record<K, V>) e devolve um construtor mais específico, fornecendo ao compilador um registro preciso dos campos configurados.
Perguntas Frequentes
A aula “Interfaces Fluentes com Tipos” é grátis?
Sim — o texto completo de “Interfaces Fluentes com Tipos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 4 aulas no total.
O que vou aprender em “Interfaces Fluentes com Tipos”?
Encadeie métodos acompanhando o estado acumulado nos tipos. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar TypeScript Academy?
Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Interfaces Fluentes com Tipos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de TypeScript Academy?
Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fundamentos do Padrão Builder
- Interfaces Fluentes com Tipos
- Exigindo Etapas Obrigatórias
- Builders Imutáveis