Kurs JavaScript i TypeScript · Moduł 6: Podstawy TypeScript
Typy podstawowe (string, number, boolean, any, unknown)
W tej lekcji12
Witaj z powrotem w naszej podróży po języku TypeScript w Parku Jurajskim! Dziś Dr. Henry Wu ma dla Ciebie szczególną lekcję. Tak jak kategoryzacja gatunków dinozaurów jest kluczowa dla ich właściwej hodowli i opieki, tak samo kategoryzacja danych w TypeScript jest fundamentalnym elementem pisania bezpiecznego kodu.
Dlaczego typy są ważne?
Bez odpowiedniej kategoryzacji, chaos szybko rozlałby się po Parku Jurajskim - wyobraź sobie karmienie drapieżników paszą dla roślinożerców lub umieszczenie małych, łagodnych gatunków w wybiegach wielkich drapieżników.
W programowaniu, typy pełnią podobną rolę - zapobiegają "mieszaniu gatunków" danych, które nie powinny być mieszane. Sprawdźmy podstawowe typy danych w TypeScript, wykorzystując przykłady związane z zarządzaniem parkiem.
String - ciągi znaków
Typ string w TypeScript reprezentuje teksty - nazwy gatunków, opisy, identyfikatory i inne dane tekstowe.
1// Deklaracja zmiennych typu string
2let nazwaGatunku: string = "Tyrannosaurus Rex";
3let kodDNA: string = "ACGTTGCA";
4let oznaczeniePaddocka: string = "P-12";
5
6// Operacje na stringach
7let pełnyOpis: string = `${nazwaGatunku} (kod DNA: ${kodDNA}) - wybieg ${oznaczeniePaddocka}`;
8console.log(pełnyOpis.toUpperCase()); // Wyświetla: "TYRANNOSAURUS REX (KOD DNA: ACGTTGCA) - WYBIEG P-12"Number - liczby
Typ number obsługuje zarówno liczby całkowite, jak i zmiennoprzecinkowe. Jest idealny do reprezentowania wieku dinozaurów, ich wagi, budżetu parku i innych wartości liczbowych.
1// Deklaracja zmiennych typu number
2let wiekDinozaura: number = 5; // w latach
3let wagaDinozaura: number = 7500.5; // w kilogramach
4let temperaturaCiała: number = 38.2; // w stopniach Celsjusza
5
6// Operacje matematyczne
7let dziennaRacjaŻywieniowa: number = wagaDinozaura * 0.05; // 5% wagi dziennie
8let rocznyKosztUtrzymania: number = dziennaRacjaŻywieniowa * 365 * 10; // koszt karmy w dolarachBoolean - wartości logiczne
Typ boolean reprezentuje wartości prawda/fałsz, idealne do śledzenia statusów, warunków czy flag w systemie parku.
1// Deklaracja zmiennych typu boolean
2let jestDrapieżnikiem: boolean = true;
3let jestAktywny: boolean = false;
4let jestDorosły: boolean = wiekDinozaura >= 3; // wartość wyliczona
5
6// Zastosowanie w logice warunkowej
7if (jestDrapieżnikiem && jestAktywny) {
8 console.log("UWAGA: Aktywny drapieżnik! Sprawdź zabezpieczenia wybiegu!");
9}
10
11// Wykorzystanie w obiekcie konfiguracyjnym
12let protokółBezpieczeństwa = {
13 wymagaPodwójnegoOgrodzenia: jestDrapieżnikiem,
14 wymagaMonitoringuNocnego: jestAktywny,
15 dozwoloneDlaZwiedzających: !jestDrapieżnikiem || !jestAktywny
16};Any - dowolny typ
Typ any jest jak nieznany gatunek dinozaura, który może zachowywać się w nieprzewidywalny sposób. Pozwala na przypisanie dowolnej wartości do zmiennej i wykonywanie na niej dowolnych operacji - co może być niebezpieczne!
1// Deklaracja zmiennych typu any
2let próbkaBadawcza: any = "DNA-123";
3próbkaBadawcza = 42; // Możemy zmienić typ na number
4próbkaBadawcza = true; // Możemy zmienić typ na boolean
5próbkaBadawcza = { typ: "krew", wiek: "nieznany" }; // Możemy zmienić typ na obiekt
6
7// Niebezpieczne operacje
8próbkaBadawcza.nieistniejącaMetoda(); // TypeScript nie zgłosi błędu!UWAGA: Dr. Wu stanowczo odradza nadużywanie typu
any- to jak wpuszczanie niezidentyfikowanych dinozaurów do parku bez odpowiednich zabezpieczeń! Używaj go tylko w ostateczności, gdy naprawdę nie wiesz, jakiego typu dane otrzymasz.
Unknown - nieznany typ, ale bezpieczniejszy
Typ unknown jest jak nowy gatunek dinozaura w kwarantannie - zanim go wypuścisz, musisz dokładnie sprawdzić jego właściwości.
1// Deklaracja zmiennych typu unknown
2let noweOdkrycie: unknown = pobierzDaneZWykopaliska();
3
4// Nie możemy wykonywać operacji bezpośrednio
5// noweOdkrycie.metoda(); // Error: Object is of type 'unknown'
6
7// Musimy najpierw sprawdzić typ
8if (typeof noweOdkrycie === "string") {
9 console.log(noweOdkrycie.toUpperCase()); // OK
10} else if (typeof noweOdkrycie === "number") {
11 console.log(noweOdkrycie.toFixed(2)); // OK
12} else if (noweOdkrycie instanceof DinoFragment) {
13 console.log(noweOdkrycie.analizujDNA()); // OK
14}Typy literałowe - ograniczenie wartości
Typy literałowe (literal types) pozwalają na zdefiniowanie ścisłego zbioru dozwolonych wartości, co jest przydatne np. przy definiowaniu gatunków dinozaurów czy stref bezpieczeństwa.
1// Typy literałowe
2type GatunekDrapieżnika = "Tyrannosaurus" | "Velociraptor" | "Spinosaurus";
3type PoziomZagrożenia = 1 | 2 | 3 | 4 | 5;
4type StatusWybiegu = "aktywny" | "w konserwacji" | "zamknięty";
5
6// Wykorzystanie typów literałowych
7let obecnyDrapieżnik: GatunekDrapieżnika = "Velociraptor";
8let zagrożenie: PoziomZagrożenia = 4;
9let statusWybieguT: StatusWybiegu = "aktywny";
10
11// Próba przypisania niedozwolonej wartości spowoduje błąd
12// obecnyDrapieżnik = "Stegosaurus"; // Error: Type '"Stegosaurus"' is not assignable to type 'GatunekDrapieżnika'Type Inference - automatyczne wykrywanie typów
TypeScript potrafi automatycznie wywnioskować typ zmiennej na podstawie przypisanej wartości, co pozwala na pisanie bardziej zwięzłego kodu.
1// Automatyczne wykrywanie typów
2let nazwaDino = "Blue"; // TypeScript wywnioskuje typ string
3let wiek = 3; // TypeScript wywnioskuje typ number
4let jestAktywna = true; // TypeScript wywnioskuje typ boolean
5
6// TypeScript zapobiega błędnemu przypisaniu
7// nazwaDino = 42; // Error: Type 'number' is not assignable to type 'string'Union Types - typy unii
Union types pozwalają na określenie, że zmienna może przyjmować wartości kilku różnych typów, co jest przydatne w wielu scenariuszach parku.
1// Deklaracja zmiennej, która może być string lub number
2let identyfikator: string | number;
3
4identyfikator = "TREX-001"; // OK
5identyfikator = 12345; // OK
6// identyfikator = true; // Error: Type 'boolean' is not assignable to type 'string | number'
7
8// Funkcja obsługująca różne typy dinozaurów
9function przetwórzDane(dane: string | number | boolean) {
10 if (typeof dane === "string") {
11 return dane.toUpperCase();
12 } else if (typeof dane === "number") {
13 return dane.toFixed(2);
14 } else {
15 return dane ? "AKTYWNY" : "NIEAKTYWNY";
16 }
17}Null i Undefined
W TypeScript, null i undefined to specjalne wartości, które mogą być użyteczne do reprezentowania braku danych, np. gdy dinozaur jeszcze nie został oznaczony tagiem RFID.
1// Z włączoną opcją strictNullChecks w tsconfig.json
2let tagRFID: string | null = null; // Dinozaur jeszcze nie otrzymał tagu
3let ostatniBadanie: Date | undefined; // Badanie jeszcze nie było przeprowadzone
4
5// Sprawdzanie przed użyciem
6function sprawdźStatus(dino: { nazwa: string, tag: string | null }) {
7 if (dino.tag === null) {
8 return `${dino.nazwa} nie posiada tagu RFID - wymaga oznaczenia`;
9 } else {
10 return `${dino.nazwa} oznaczony tagiem ${dino.tag}`;
11 }
12}Praktyczne zastosowanie typów podstawowych
Rozważmy system monitorowania zdrowia dinozaurów, gdzie używamy różnych typów danych:
1// Interfejs opisujący strukturę danych dinozaura
2interface DaneDinozaura {
3 id: number;
4 nazwa: string;
5 gatunek: string;
6 wiek: number;
7 waga: number;
8 jestDrapieżnikiem: boolean;
9 statusZdrowia: "dobry" | "średni" | "wymaga uwagi" | "krytyczny" | null;
10 tagRFID: string | null;
11 ostatnieBadanie: Date | undefined;
12}
13
14// Funkcja sprawdzająca, czy dinozaur wymaga interwencji weterynarza
15function wymagaInterwencji(dino: DaneDinozaura): boolean {
16 // Dinozaur wymaga interwencji, jeżeli:
17 // - jego status zdrowia jest krytyczny
18 // - nie miał badania w ciągu ostatnich 30 dni
19 // - nie posiada tagu RFID
20
21 const dzisiaj = new Date();
22 const trzydzieściDniWstyecz = new Date();
23 trzydzieściDniWstyecz.setDate(dzisiaj.getDate() - 30);
24
25 return (
26 dino.statusZdrowia === "krytyczny" ||
27 dino.statusZdrowia === null ||
28 dino.tagRFID === null ||
29 (dino.ostatnieBadanie === undefined || dino.ostatnieBadanie < trzydzieściDniWstyecz)
30 );
31}
32
33// Przykładowe wykorzystanie
34const raptorBlue: DaneDinozaura = {
35 id: 101,
36 nazwa: "Blue",
37 gatunek: "Velociraptor",
38 wiek: 5,
39 waga: 350,
40 jestDrapieżnikiem: true,
41 statusZdrowia: "dobry",
42 tagRFID: "VR-101-BLUE",
43 ostatnieBadanie: new Date("2023-08-15")
44};
45
46const trixie: DaneDinozaura = {
47 id: 205,
48 nazwa: "Trixie",
49 gatunek: "Triceratops",
50 wiek: 12,
51 waga: 8500,
52 jestDrapieżnikiem: false,
53 statusZdrowia: "wymaga uwagi",
54 tagRFID: "TC-205-TRIXIE",
55 ostatnieBadanie: undefined
56};
57
58console.log(`Blue wymaga interwencji: ${wymagaInterwencji(raptorBlue)}`);
59console.log(`Trixie wymaga interwencji: ${wymagaInterwencji(trixie)}`);Podsumowanie
Właściwe używanie typów podstawowych w TypeScript jest jak precyzyjne zarządzanie różnymi gatunkami dinozaurów w Parku Jurajskim - zapewnia bezpieczeństwo i przewidywalność.
| Typ | Zastosowanie w Parku Jurajskim | Przykład | ||
|---|---|---|---|---|
| string | Nazwy, opisy, identyfikatory | "Velociraptor", "P-12" | ||
| number | Wiek, waga, koszty | 5, 7500.5, 38.2 | ||
| boolean | Statusy, warunki, flagi | true, false | ||
| any | Dane o nieznanej strukturze (używaj z rozwagą!) | System legacy, dane zewnętrzne | ||
| unknown | Bezpieczniejsza alternatywa dla any | Dane, które wymagają walidacji | ||
| union types | Wartości, które mogą być różnych typów | string | number | null |
| literal types | Ograniczony zestaw wartości | "aktywny" | "nieaktywny" |
W następnej lekcji przyjrzymy się bardziej złożonym typom, takim jak tablice, krotki i enumeracje, które pozwolą nam na jeszcze lepsze modelowanie struktury danych naszego parku.
Dr. Henry Wu przypomina: "Tak jak w genetyce dinozaurów, w TypeScript precyzja typów jest kluczem do sukcesu i uniknięcia... niespodzianek."
Kod do tej lekcji: index.ts
1// Typy podstawowe w Parku Jurajskim
2console.log("Typy podstawowe TypeScript\n");
3
4// ===========================================
5// 1. STRING - teksty
6// ===========================================
7console.log("=== TYP STRING ===");
8
9let species: string = "Tyrannosaurus Rex";
10let dnaCode: string = "ACGTTGCA";
11let paddockId: string = "P-12";
12
13// Template literals
14let fullDescription: string = `${species} (DNA: ${dnaCode}) - Paddock ${paddockId}`;
15console.log(fullDescription);
16console.log(`Uppercase: ${species.toUpperCase()}`);
17
18// ===========================================
19// 2. NUMBER - liczby
20// ===========================================
21console.log("\n=== TYP NUMBER ===");
22
23let age: number = 5; // lata
24let weight: number = 7500.5; // kg
25let temperature: number = 38.2; // °C
26let hexValue: number = 0xFF; // 255
27let binaryValue: number = 0b1010; // 10
28
29console.log(`Age: ${age} years`);
30console.log(`Weight: ${weight}kg`);
31console.log(`Temperature: ${temperature}°C`);
32
33// Operacje matematyczne
34let dailyFeed: number = weight * 0.05;
35let yearlyFeedCost: number = dailyFeed * 365 * 10;
36console.log(`Daily feed: ${dailyFeed}kg`);
37console.log(`Yearly cost: $${yearlyFeedCost}`);
38
39// ===========================================
40// 3. BOOLEAN - wartości logiczne
41// ===========================================
42console.log("\n=== TYP BOOLEAN ===");
43
44let isCarnivore: boolean = true;
45let isActive: boolean = false;
46let isAdult: boolean = age >= 3;
47let isHungry: boolean = true;
48let isDangerous: boolean = isCarnivore && isHungry;
49
50console.log(`Is carnivore: ${isCarnivore}`);
51console.log(`Is active: ${isActive}`);
52console.log(`Is adult: ${isAdult}`);
53console.log(`Is dangerous: ${isDangerous}`);
54
55// Logika warunkowa
56if (isDangerous) {
57 console.log("Security level: CRITICAL");
58} else {
59 console.log("Security level: NORMAL");
60}
61
62// ===========================================
63// 4. ANY - dowolny typ (unikaj!)
64// ===========================================
65console.log("\n=== TYP ANY ===");
66
67let mysteryData: any = "unknown";
68mysteryData = 123; // OK
69mysteryData = true; // OK
70mysteryData = { type: "fossil" }; // OK
71
72console.log("ANY nie sprawdza typów - używaj ostrożnie!");
73console.log("Mystery data:", mysteryData);
74
75// ===========================================
76// 5. UNKNOWN - bezpieczniejszy any
77// ===========================================
78console.log("\n=== TYP UNKNOWN ===");
79
80let unknownData: unknown = "mysterious DNA sequence";
81
82// Musimy sprawdzić typ przed użyciem
83if (typeof unknownData === 'string') {
84 console.log("Unknown data length:", unknownData.length);
85} else {
86 console.log("Not a string");
87}
88
89console.log("UNKNOWN wymaga sprawdzenia typu");
90
91// ===========================================
92// 6. NULL i UNDEFINED
93// ===========================================
94console.log("\n=== NULL I UNDEFINED ===");
95
96let emptyValue: null = null;
97let notInitialized: undefined = undefined;
98
99let optionalSpecies: string | null = null; // może być string lub null
100let optionalAge: number | undefined; // może być number lub undefined
101
102console.log("Empty value:", emptyValue);
103console.log("Not initialized:", notInitialized);
104console.log("Optional species:", optionalSpecies);
105console.log("Optional age:", optionalAge);
106
107// Sprawdzanie null/undefined
108function displaySpecies(s: string | null): void {
109 if (s !== null) {
110 console.log(`Species: ${s}`);
111 } else {
112 console.log("Species unknown");
113 }
114}
115
116displaySpecies(species);
117displaySpecies(null);
118
119// ===========================================
120// 7. Podsumowanie
121// ===========================================
122console.log("\n=== PODSUMOWANIE ===");
123console.log("string - teksty i znaki");
124console.log("number - liczby (int, float, hex, binary)");
125console.log("boolean - true/false");
126console.log("any - dowolny typ (unikaj)");
127console.log("unknown - bezpieczniejszy any");
128console.log("null - brak wartości");
129console.log("undefined - niezainicjalizowane");
130
131console.log("\nTypy podstawowe opanowane!");Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co robi operator : po nazwie zmiennej w TypeScript?
Zadania praktyczne w grze
- Edytor kodu
Zdefiniuj zmienne z typami string, number i boolean opisujące dinozaura.
- Układanie w poziomie
Ułóż elementy deklaracji zmiennej z typem w TypeScript:
- Klikanie w kolejności
Ułóż elementy funkcji TypeScript z typami: