Kurs JavaScript i TypeScript · Moduł 6: Podstawy TypeScript

Typy podstawowe (string, number, boolean, any, unknown)

7 min czytania
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 dolarach

Boolean - 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ść.

TypZastosowanie w Parku JurajskimPrzykład
stringNazwy, opisy, identyfikatory"Velociraptor", "P-12"
numberWiek, waga, koszty5, 7500.5, 38.2
booleanStatusy, warunki, flagitrue, false
anyDane o nieznanej strukturze (używaj z rozwagą!)System legacy, dane zewnętrzne
unknownBezpieczniejsza alternatywa dla anyDane, które wymagają walidacji
union typesWartości, które mogą być różnych typówstringnumbernull
literal typesOgraniczony 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. 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:

Przydatne artykuły