0Pricing
TypeScript Academy · Lekcja

Fluent interfaces z typami

Łącz wywołania metod, śledząc narastający stan w typach

Fluent interfaces z typami to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 4 lekcji w sumie.

Śledzenie ustawionych elementów

Prosty builder pozwala wywołać build() w dowolnym momencie, nawet gdy brakuje wymaganych pól. Można zrobić to lepiej, śledząc zgromadzony stan w systemie typów za pomocą parametru typu generycznego.

Parametr typu stanu

Builder otrzymuje generyczny typ S, który rejestruje klucze podane do tej pory. Przy każdym wywołaniu metody rozszerzamy S, dodając nowy klucz.

class Builder<S> {
  // S is a record of keys set so far, e.g. {} or { url: string }
  private data: Record<string, unknown> = {};
}

Każda metoda dodaje klucz

Setter zwraca nowy typowany builder, którego S zawiera właśnie dodany klucz. W czasie działania programu wartość jest przechowywana, a typ odpowiednio się rozszerza.

  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>>;
  }

Sztuczka z przecięciem typów

Wyrażenie S & Record<K, V> tworzy przecięcie poprzedniego stanu z nowym kluczem. Po dwóch wywołaniach typ dokładnie zna oba klucze.

type Empty = {};
type AfterUrl = Empty & Record<"url", string>;
type AfterBoth = AfterUrl & Record<"method", string>;
// AfterBoth = { url: string; method: string }

Konkretny builder fluentowy

W tym przykładzie builder żądania przekazuje zgromadzoną strukturę przez każde kolejne wywołanie. Kompilator zawsze dokładnie wie, które pola istnieją.

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;
  }
}

Typ rośnie wraz z łańcuchem wywołań

Każde wywołanie w łańcuchu tworzy bardziej szczegółowy typ buildera. Umieszczenie wskaźnika myszy nad wynikiem w edytorze pokazuje zgromadzony stan.

const partial = new Req<{}>().url("/x");
// type: Req<{ url: string }>
const full = partial.method("POST");
// type: Req<{ url: string; method: string }>

Po co w ogóle śledzić stan?

Gdy typ zawiera zbiór podanych kluczy, można później ograniczyć build() tak, aby kompilował się tylko wtedy, gdy obecne są wymagane klucze. Parametr stanu stanowi podstawę tego gwarantowanego zachowania.

Odczytywanie zgromadzonej struktury

Można wyodrębnić zgromadzoną strukturę, aby ją sprawdzić. Potwierdza to, że typ buildera dokładnie odzwierciedla skonfigurowane elementy.

type StateOf<T> = T extends Req<infer S> ? S : never;
type S1 = StateOf<Req<{ url: string }>>; // { url: string }

Działanie programu pozostaje proste

Cała złożoność znajduje się w typach. W czasie działania programu każdy setter po prostu przechowuje wartość w obiekcie. Rzutowania (as any) łączą obiekt czasu działania z bogatszym typem używanym podczas kompilacji.

const r = new Req<{}>().url("/users").method("GET");
console.log("configured url and method");

Stan generyczny jako rejestr

Można myśleć o S jak o rejestrze ustawionych elementów. Metody dopisują do niego kolejne wpisy, a etap budowania może później odczytać rejestr i zdecydować, czy konstrukcja jest dozwolona.

Kompromisy

Śledzenie stanu na poziomie typów zapewnia precyzyjne informacje w środowisku IDE i zapobiega niekompletnemu budowaniu, ale wymaga kilku rzutowań i bardziej zaawansowanych typów generycznych. Opłaca się to w przypadku interfejsów API używanych przez wiele osób.

Szybkie sprawdzenie

Szybkie sprawdzenie wiadomości z tej lekcji.

Podsumowanie

Typowany builder fluentowy przechowuje generyczny parametr stanu S. Każdy setter tworzy przecięcie S z nowym kluczem (S & Record<K, V>) i zwraca bardziej szczegółowy builder, zapewniając kompilatorowi precyzyjny rejestr skonfigurowanych pól.

Często zadawane pytania

Czy lekcja „Fluent interfaces z typami” jest bezpłatna?

Tak — pełny tekst „Fluent interfaces z typami” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Fluent interfaces z typami”?

Łącz wywołania metod, śledząc narastający stan w typach Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?

Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Fluent interfaces z typami”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?

Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy wzorca Builder
  2. Fluent interfaces z typami
  3. Wymuszanie wymaganych kroków
  4. Niezmienne obiekty Builder
← Powrót do TypeScript Academy