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
- Rekurencyjne definicje typów
- Typowanie struktur drzewiastych
- Typy wartości JSON
- Głębokość i ograniczenia rekurencji