TypeScript típusok
A gyakorlat anyaga¶
Alap típusok¶
Az alapvető típusokat már láttuk az előző gyakorlaton, túl sok újdonság nincs bennük a látottakon felül.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Tömb típus¶
A tömbök azonos típusú (!) elemek gyűjteményét tárolják. Két szintaxis létezik, de a Type[] a preferált, az Array<Type> ritkábban használt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Ha egy tömbből csak olvasni szeretnénk a kezdeti feltöltés után, érdemes a readonly módosítót használni, így garantálhatjuk, hogy a tömb nem módosítható.
A kulcsszó a típus elé kerüljön, ahogy a lenti példán is látható.
1 2 | |
Union típus¶
A union típusok lehetővé teszik, hogy egy érték több típus egyike legyen. Az | operátorral jelöljük.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Természetesen itt is lehet megadni null értéket, így vagy adott típust kapunk, vagy null-t.
1 2 3 4 5 6 7 8 9 | |
Arra is van lehetőségünk, hogy típusok helyett konkrétan értékeket adjunk csak meg, amelyek egyikét fel fogja venni az adott változó. Minden más esetben pedig hiba történik.
1 2 3 4 5 6 7 8 9 | |
Discriminated Union (Megkülönböztető unió)¶
A discriminated union (más néven tagged union) egy speciális union típus minta, ahol minden típusnak van egy közös property-je (általában kind, type vagy tag néven), amely egyedileg azonosítja a típust. Ez a property teszi lehetővé a TypeScript számára, hogy automatikusan leszűkítse a típust, amikor ellenőrizzük az értékét.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
A union típusok rugalmas és típusbiztos megoldást nyújtanak. A discriminated union minta egy kind vagy type mezővel teszi tisztábbá a típus leszűkítést is.
Ahogy látszik is, ezek használata azért nem kifejezetten egyszerű, azonban a típusbiztosság miatt gyakran megéri.
Type alias (Típus alias)¶
A type kulcsszóval egyedi típusneveket hozhatunk létre, amelyek egyszerűbbé és olvashatóbbá teszik a kódot. A type alias-ok különösen hasznosak komplex típusok esetén, union típusoknál, objektum struktúrák definiálásánál, és függvény szignatúrák megadásánál. A type alias-ok nem hoznak létre új típust, csak egy új nevet adnak egy meglévő típusnak vagy típuskombinációnak.
Nagyon hasznosak gyakran használt union típusoknál is.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Természetesen nem csak itt használhatjuk, sok esetben hasznos lehet.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Illetve komplex objektumok formáját is leírhatjuk velük.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Tetszőleges módon egymásba is ágyazhatjuk ezeket.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Enum típus¶
Az enumokkal elnevezett konstansokat hozhatunk létre, nagyon hasonlítanak más nyelvekben lévő enum típusokra. A string enumok általában jobbak debuggoláshoz TypeScriptben.
Numerikus enumok esetén az egyes konstansokhoz tartozó értékek számértékek lesznek:
1 2 3 4 5 6 7 8 9 | |
Természetesen arra is lehetőségünk van, hogy egyéni értékekkel lássuk el az egyes konstans értékeket.
1 2 3 4 5 6 7 8 | |
Szöveges enumok létrehozására is van lehetőség. Ebben az esetben minden konstansnak egy szöveges értéket állítunk be.
1 2 3 4 5 6 7 8 9 10 11 12 | |
Any típus¶
Az any típus kikapcsolja a típusellenőrzést. Ezt érdemes kerülni az esetek jelentős részében - ez felülírja a TypeScript alapvető célját.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Érdemes az any helyett a unknown-t használni, vagy pedig valódi típusokat, amennyiben tudjuk azokat. Egyetlen kivétel ez alól az, amikor a létező JavaScript kódbázisunkat migráljuk TypeScriptre. Ebben az esetben a kezdeti átírás lehet például any, de ezt a lehető legrövidebb időn belül érdemes lecserélni.
Az any szűrésére több eszköz is létezik, például az ESLint elemzőnek is van ide vonatkozó szabálya. Vagy például a noImplicitAny konfigurációt be lehet kapcsolni a tsconfig.json-ben
Void típus¶
A void típus azt jelzi, hogy egy függvény semmit sem ad vissza. Kizárólag függvény visszatérési típusokhoz használjuk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
És bizony, tömbökkel kapcsolatos, vagy bármilyen egyéb, callbacket használó művelet esetén is használhatunk típusokat, például az arrow function-ökben is.
1 2 3 4 5 | |
Never típus¶
A never típus olyan értékeket reprezentál, amelyek soha nem következnek be. Használatos hibát dobó függvényeknél és exhaustive type checking-nél (kimerítő típusellenőrzés, amikor az összes lehetséges típust ellenőrizzük, és pl. egy default vagy else ágba garantáltan nem juthatunk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
A never típus biztosítja, hogy minden esetet kezelj bizonyos helyzetekben. Ha új típust adsz hozzá, de elfelejted kezelni, fordítási hibát kapsz.
Unknown típus¶
Az unknown típus az any típusbiztos alternatívája. Bármilyen értéket elfogad, de használat előtt típusellenőrzés szükséges.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Az unknown használata biztosítja, hogy minden adatot validáljunk használat előtt, így elkerülhetjük a futási idejű hibákat.
Type Casting (Típuskényszerítés)¶
A type casting megmondja a TypeScript-nek, hogy egy értéket adott típusúként kezeljen. Óvatosan használjuk, mert megkerüli a típusbiztonságot.
1 2 | |
Emellett használhatjuk a kacsacsőrökkel jelölt angle bracket szintaxist is, például (<string>someValue).length.
Azonban ezt érdemes lehet kerülni, mert JSX/React kódokban nem fog működni (de ezzel ez a kurzus nem foglalkozik).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
A type casting azonban NEM konvertál, erre nagyon figyeljünk! Csak a fordítónak mondjuk meg, hogyan kezelje az adott értéket, de ezzel nem garantáljuk, hogy valóban olyan típusúvá alakuljon az adott érték (ha valódi típuskonverziót szeretnénk, használjunk konverziós függvényeket).
1 2 3 | |
A TypeScript akkor a legerősebb, amikor együtt dolgozol a típusrendszerrel, nem ellene. A fordító segít, nem akadályoz!
Gyakorló feladatok¶
-
Felhasználói jogosultságok
Készíts egy
UserRoletype alias-t, amely csak a következő értékeket veheti fel: "admin", "editor", "viewer". Írj egycheckPermissionfüggvényt, amely egy szerepkört és egy műveletet kap, és visszaadja string-ként, hogy a felhasználó végrehajthatja-e: - "admin" mindent megtehet - "editor" csak olvasni és szerkeszteni tud - "viewer" csak olvasni tudA művelet lehet: "read", "edit", "delete" (szintén készíts hozzá type alias-t).
-
Termék katalógus
Definiálj egy
Producttype alias-t a következő tulajdonságokkal:id: numbername: stringprice: numberinStock: booleancategory: "electronics" | "books" | "clothing"description: opcionális string
Írj egy függvényt, amely egy termék tömböt kap, és visszaadja csak azokat a termékeket, amelyek raktáron vannak.
-
API válasz kezelő
Egy API-tól különböző típusú válaszokat kaphatunk. Készíts discriminated union-t a következő válaszokra:
- Sikeres válasz:
{ status: "success", data: any } - Hibaüzenet:
{ status: "error", message: string } - Betöltés állapot:
{ status: "loading" }
Írj egy
handleApiResponsefüggvényt, amely feldolgozza ezeket a válaszokat és megfelelő üzenetet ír ki console.log-ba. - Sikeres válasz:
-
Rendelés státusz enum
Készíts egy
OrderStatusenumot a következő értékekkel:- Pending (érték: "PENDING")
- Processing (érték: "PROCESSING")
- Shipped (érték: "SHIPPED")
- Delivered (érték: "DELIVERED")
- Cancelled (érték: "CANCELLED")
Írj egy
getStatusMessagefüggvényt, amely egy OrderStatus-t kap, és visszaad egy magyar nyelvű leírást a státuszról. -
Bankszámla műveletek
Készíts típusdefiníciókat egy banki rendszerhez: -
Accounttype: accountNumber (string), balance (number), owner (string) -TransactionTypeunion: "deposit" | "withdrawal" | "transfer" -Transactiontype: type (TransactionType), amount (number), timestamp (Date), fromAccount? (optional string), toAccount? (optional string)Írj egy
processTransactionfüggvényt, amely egy számlát és egy tranzakciót kap, és visszaadja az új számlaállást. Withdrawal esetén ellenőrizd, hogy van-e elég fedezet (ha nincs, térj vissza null-lal)!