0Pricing
TypeScript Academy · Lekcja

Rekurencyjne definicje typów

Bezpiecznie zapisuj typy odwołujące się do samych siebie

Rekurencyjne definicje typów to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 1 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.

Czym jest typ rekurencyjny

Typ rekurencyjny to typ, który odwołuje się do samego siebie w swojej definicji. Pozwala to opisywać struktury danych o nieograniczonej głębokości.

type LinkedList<T> = {
  value: T;
  next: LinkedList<T> | null;
};
// next is the same type again, ending at null.

Typ listy jednokierunkowej

Klasyczny przykład: każdy węzeł przechowuje value oraz wskaźnik next do kolejnego węzła albo null, który kończy łańcuch.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const list: LinkedList<number> = {
  value: 1,
  next: { value: 2, next: null }
};
console.log(list.value, list.next?.value);

Przypadek bazowy ma znaczenie

Każdy typ rekurencyjny potrzebuje elementu kończącego — tutaj jest nim null — aby rekurencja mogła się zakończyć. Bez niego typ miałby nieskończoną głębokość.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const single: LinkedList<string> = { value: "only", next: null };
console.log(single.next);

Budowanie dłuższych łańcuchów

Można zagnieżdżać elementy tak głęboko, jak to potrzebne; typ pozwala na dowolną długość, ponieważ next jest samo w sobie listą albo wartością null.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const chain: LinkedList<number> = {
  value: 10,
  next: { value: 20, next: { value: 30, next: null } }
};
console.log(chain.next?.next?.value);

Przechodzenie listy jednokierunkowej

Funkcja może przejść przez łańcuch, podążając za next aż do napotkania null. Typ rekurencyjny zapewnia przy tym pełne bezpieczeństwo typów.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function toArray<T>(list: LinkedList<T> | null): T[] {
  const out: T[] = [];
  let cur = list;
  while (cur) { out.push(cur.value); cur = cur.next; }
  return out;
}
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(toArray(l));

Funkcje rekurencyjne dla typów rekurencyjnych

Typy rekurencyjne naturalnie współpracują z funkcjami rekurencyjnymi. W tym przykładzie długość jest obliczana przez rekurencyjne wywoływanie funkcji dla next.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function length<T>(list: LinkedList<T> | null): number {
  return list === null ? 0 : 1 + length(list.next);
}
const l: LinkedList<string> = { value: "a", next: { value: "b", next: null } };
console.log(length(l));

Dodawanie elementu na początku listy

Ponieważ typ ma jednolitą strukturę, tworzenie nowych list jest proste: wystarczy umieścić istniejącą listę jako next nowego węzła będącego początkiem listy.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function prepend<T>(value: T, list: LinkedList<T> | null): LinkedList<T> {
  return { value, next: list };
}
const l = prepend(1, prepend(2, null));
console.log(l.value, l.next?.value);

Opcjonalne i dopuszczające null elementy kończące

Rekurencję można zakończyć za pomocą null albo oznaczyć next jako opcjonalne. Oba rozwiązania kończą rekurencję; należy wybrać to, które najlepiej odpowiada sposobowi reprezentowania końca.

type ListA<T> = { value: T; next: ListA<T> | null };
type ListB<T> = { value: T; next?: ListB<T> };
const a: ListA<number> = { value: 1, next: null };
const b: ListB<number> = { value: 1 };
console.log(a.value, b.value);

Typy rekurencyjne są rozwijane leniwie

TypeScript rozwija typ rekurencyjny tylko tak daleko, jak jest on rzeczywiście używany. Definicja może odwoływać się do samej siebie bez powodowania nieskończonej pracy.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
// Using two levels only expands two levels.
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(l.next?.value);

Mapowanie listy

Rekurencyjne mapowanie przekształca każdą wartość, zachowując strukturę i zwracając nową listę o takim samym kształcie.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function mapList<T, U>(list: LinkedList<T> | null, fn: (v: T) => U): LinkedList<U> | null {
  if (list === null) return null;
  return { value: fn(list.value), next: mapList(list.next, fn) };
}
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(mapList(l, x => x * 10)?.value);

Dlaczego typy rekurencyjne są potężne

Typy odwołujące się do samych siebie pozwalają modelować dowolnie zagnieżdżone dane, listy, drzewa i JSON, zapewniając pełne bezpieczeństwo typów bez stałego limitu głębokości w projekcie.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const l: LinkedList<boolean> = { value: true, next: { value: false, next: null } };
console.log(l.value, l.next?.value);

Szybki test: typy rekurencyjne

Proszę sprawdzić, czy rozumie Pan/Pani definicje typów rekurencyjnych.

Podsumowanie: definicje typów rekurencyjnych

Dowiedział się Pan/Dowiedziała się Pani, że typ rekurencyjny odwołuje się do samego siebie, potrzebuje przypadku bazowego, takiego jak null, aby zakończyć rekurencję, i naturalnie współpracuje z funkcjami rekurencyjnymi służącymi do przechodzenia, mapowania oraz budowania list jednokierunkowych.

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const l: LinkedList<number> = { value: 1, next: null };
console.log(l.value);

Często zadawane pytania

Czy lekcja „Rekurencyjne definicje typów” jest bezpłatna?

Tak — pełny tekst „Rekurencyjne definicje typów” 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 „Rekurencyjne definicje typów”?

Bezpiecznie zapisuj typy odwołujące się do samych siebie Ć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 1 z 4.

Ile czasu zajmuje lekcja „Rekurencyjne definicje typów”?

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. Rekurencyjne definicje typów
  2. Typowanie struktur drzewiastych
  3. Typy wartości JSON
  4. Głębokość i ograniczenia rekurencji
← Powrót do TypeScript Academy