Zawężanie na podstawie właściwości rozróżniającej
Pozwól TypeScriptowi zawężać warianty w instrukcjach switch
Zawężanie na podstawie właściwości rozróżniającej 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.
Zawężanie na podstawie dyskryminatora
Po sprawdzeniu dyskryminatora TypeScript zawęża unię do pasującego elementu i udostępnia jego specyficzne pola. To właśnie najważniejsza korzyść tego wzorca.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape) {
if (s.kind === "circle") return Math.PI * s.radius ** 2;
return s.side ** 2;
}
console.log(area({ kind: "circle", radius: 2 }).toFixed(2));Instrukcja switch na dyskryminatorze
Instrukcja switch oparta na dyskryminatorze to najczytelniejszy sposób obsługi każdego wariantu. W każdym bloku case typ jest automatycznie zawężany.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
}
}
console.log(area({ kind: "square", side: 5 }));Pola właściwe dla elementu w każdym przypadku
W przypadku "circle" pole s.radius jest dostępne, ale s.side już nie. TypeScript dokładnie wie, w którym elemencie unii znajduje się program.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function describe(s: Shape) {
switch (s.kind) {
case "circle": return "r=" + s.radius;
case "square": return "side=" + s.side;
}
}
console.log(describe({ kind: "circle", radius: 9 }));Zawężanie na podstawie if
Nie trzeba używać instrukcji switch. Proste porównanie dyskryminatora w instrukcji if zawęża typ równie skutecznie.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function perimeter(s: Shape): number {
if (s.kind === "circle") {
return 2 * Math.PI * s.radius;
}
return 4 * s.side;
}
console.log(perimeter({ kind: "square", side: 3 }));Dostęp do niewłaściwego pola kończy się błędem
Przed zawężeniem nie można odwoływać się do pola właściwego tylko dla jednego elementu unii. TypeScript zgłasza błąd, ponieważ ta właściwość nie istnieje w każdym elemencie.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function broken(s: Shape) {
// Error: radius does not exist on Square
// return s.radius;
return s.kind;
}
console.log(broken({ kind: "square", side: 1 }));Zawężanie z dyskryminatorami logicznymi
W przypadku unii { ok: true } | { ok: false } sprawdzenie if (r.ok) zawęża typ do elementu oznaczającego powodzenie.
type Result =
| { ok: true; data: string }
| { ok: false; error: string };
function handle(r: Result): string {
if (r.ok) return "Data: " + r.data;
return "Error: " + r.error;
}
console.log(handle({ ok: false, error: "boom" }));Zawężanie przez wcześniejszy return
Wczesne zakończenie funkcji dla jednego wariantu zawęża pozostały kod do innych wariantów. Jest to wygodny sposób obsługiwania przypadków po kolei.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function label(s: Shape): string {
if (s.kind === "circle") return "circle";
// s is now narrowed to Square here
return "square with side " + s.side;
}
console.log(label({ kind: "square", side: 8 }));Łączenie z innymi warunkami
Sprawdzenie dyskryminatora można łączyć z inną logiką. TypeScript zachowuje zawężenie, dopóki warunek dotyczący dyskryminatora jest prawdziwy w danej gałęzi.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function bigCircle(s: Shape): boolean {
return s.kind === "circle" && s.radius > 100;
}
console.log(bigCircle({ kind: "circle", radius: 150 }));Zawężanie w filtrach tablic
Zawężanie działa również wewnątrz funkcji zwrotnych. W tym przykładzie każda figura jest sprawdzana osobno podczas iteracji.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
const shapes: Shape[] = [
{ kind: "circle", radius: 1 },
{ kind: "square", side: 2 }
];
shapes.forEach(s => {
if (s.kind === "circle") console.log("c", s.radius);
else console.log("s", s.side);
});Zwracanie z instrukcji switch zachowuje bezpieczeństwo typów
Gdy instrukcja switch obsługuje każdy przypadek i zwraca wartość, TypeScript wyprowadza precyzyjny typ zwracany na podstawie unii wyników ze wszystkich przypadków.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function tag(s: Shape) {
switch (s.kind) {
case "circle": return s.radius;
case "square": return s.side;
}
}
console.log(tag({ kind: "circle", radius: 4 }));Łączenie wszystkich elementów zawężania
Niezależnie od tego, czy używają Państwo switch, czy if, sprawdzenie dyskryminatora umożliwia bezpieczny dostęp do pól elementu. W następnej części zagwarantujemy obsługę każdego przypadku.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(s: Shape): number {
return s.kind === "circle" ? Math.PI * s.radius ** 2 : s.side ** 2;
}
console.log(Math.round(area({ kind: "circle", radius: 10 })));Szybkie sprawdzenie: zawężanie
Sprawdź, czy rozumiesz zawężanie na podstawie dyskryminatora.
Podsumowanie: zawężanie na podstawie dyskryminatora
Zobaczyli Państwo, że sprawdzenie dyskryminatora za pomocą switch lub if zawęża unię do jednego elementu i udostępnia tylko jego pola. Wczesne zakończenia funkcji oraz połączone warunki również zachowują zawężenie.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
const s: Shape = { kind: "square", side: 7 };
console.log(s.kind === "square" ? s.side : 0);Często zadawane pytania
Czy lekcja „Zawężanie na podstawie właściwości rozróżniającej” jest bezpłatna?
Tak — pełny tekst „Zawężanie na podstawie właściwości rozróżniającej” 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 „Zawężanie na podstawie właściwości rozróżniającej”?
Pozwól TypeScriptowi zawężać warianty w instrukcjach switch Ć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 „Zawężanie na podstawie właściwości rozróżniającej”?
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
- Budowanie unii rozróżnianych
- Zawężanie na podstawie właściwości rozróżniającej
- Sprawdzanie kompletności za pomocą never
- Modelowanie automatów stanów