Razlika između 'type' i 'interface' u TypeScriptu
Slaven Bunijevac
Posted on April 13, 2024
TypeScript je sjajan alat koji donosi nove mogućnosti, koje ne postoje u JavaScriptu. Glavna stvar koju TypeScript razlikuje od JavaScripta je to što možemo definisati tipove podataka sa kojim radimo.
Jedan od načina da se definiše tip podataka je korištenje tipa, odnosno type
aliasa, a drugi je korištenje interfejsa, odnosno interface
. Upravo razlika između ova dva načina je tema ovog teksta.
Uvod
U ovom uvodu ću da postavim osnovno okruženje i kontekst koji će biti isti za sve sljedeće primjere, da se ne bi ponavljao u narednim poglavljima.
Recimo na primjer da imam neku komponentu User
koja će dobiti podatke o korisniku u props
objektu koji ćemo prema TypeScript konvenciji opisati/definisati sa UserProps
.
Ako pokušam da opišem objekat sa UserProps
, a taj UserProps
ne postoji nigdje TypeScript će me upozoriti.
Osnovna sintaksa
Postoje dvije osnovne sintaksičke razlike. Tip koristi ključnu riječ type
, a interfejs interface
.
Druga razlika je što tip koristi znak jednakosti, a interfejs ne koristi.
U narednim primjerima ću nazive tipova počinjati sa slovom 'T', a interfejse sa slovom 'I'. Ovo se može pronaći negdje kao konvencija, ali nije neophodno raditi.
Proširivanje i naslijeđivanje
Recimo na primjer da imam nekog korisnika kog sam definisao preko tipa kao TUserProps
, ali kasnije dodajem definiciju za administratora koji ima sva svojstva kao i korisnik, plus još neka.
Kod tipova se ovo zove ukrštanje ili preklapanje (ENG: 'intersection'), odnosno dva tipa se preklapaju po nekim svojstvima. Znak ampersand ('&') sam iskoristio da spojim već definisani TUserProps i nova svojstva koja želim da dodati administratoru.
Interfejs sa druge strane koristi ključnu riječ extends
da spoji dvije definicije. Ova sintaksa će biti poznata ljudima koji koriste klase u JavaScriptu/TypeScriptu.
Kod interfejsa se ova tehnika zove naslijeđivanje. Dakle, objekat IAdminProps će naslijediti sva svojstva koja postoje u objektu IUserProps ime
i godine
, pa sam mu dodao ulogu
.
Objekti i sve ostalo
Interfejsom se mogu definisati samo objekti, dok se tipom mogu definisati objekti, ali i sve ostalo.
Ako želim da definišem objekat mogu koristiti interfejs ili tip.
Međutim, ako želim da definišem bilo šta drugo moram koristiti tip.
Nije moguće koristiti interfejs za definisanje primitivnih tipova.
Unije
Tipove je moguće koristiti da definisanje unija (skupova). Lako se može dogoditi na primjer da želimo da pohranimo neku primitivnu vrijednost, ali i da eventualno pratimo niz takvih vrijednosti.
Utility tipovi
U TypeScriptu postoje 'utility' tipovi koji nam omogućuju neke posebne funkcionalnosti. Recimo da npr. želim da iskoristim Omit
utility tip kako bi izostavio neko svojstvo objekta.
Sa type
aliasom bi to izgledalo ovako.
Ovo je tehnički moguće uraditi i sa interfejsom, ali uz mnogo ružniju sintaksu.
Morao sam iskoristiti ključnu riječ extends
, a morao sam staviti i prazne vitičaste zagrade na kraju deklaracije.
Tuple
Tupl (ENG. Tuple) je specijalna vrsta niza u TypeScriptu. To je niz koji ima fiksno definisanu dužinu. Dužina tupla se ne može naknadno mijenjati.
Ako bi želio definisati neki tip kao tupl preko type
aliasa, to je lako uraditi.
Kao što se vidi iz primjera korištenje interfejsa je mnogo obimnije i teže za čitanje. Tip je za ove situacije mnogo bolje rješenje.
Izvlačenje
Tip se može iskoristiti da se izvuče neka struktura iz objekta. Recimo na primjer da imam neki objekat stan
. Ako želim da izvučem npr. svojstvo 'specifikacije' iz tog objekta tip je sjajno rješene.
Iskoristio sam svojstvo iz objekta kako bi definisao tip.
Ovo je moguće i sa interfejsom, ali kao što se vidi iz primjera sa unijama i tuplovima mora se koristiti ključna riječ extends
, tako da je pristup sa tipovima mnogo bolji.
Spajanje i ponovna deklaracija
Jedna od situacija na koje se sasvim realno može naići je da se na projektu nađu definisane dvije strukture sa istim imenom. Ako se to dogodi sa interfejsom one će jednostavno biti spojene.
Kao što se vidi u primjeru sva svojstva iz svakog interfejsa su obavezna u novom objektu user
. Ovo može biti korisno, ako se na primjer koristi neka biblioteka iz koje dobijamo neki interfejs, pa želimo da ga proširimo.
Međutim, može biti i veoma loše jer lako može doći do neželjenih izmjena interfejsa.
Sa tipovima ovo nije moguće. TypeScript će odmah izbaciti grešku ukoliko se pojave dva tipa sa istim nazivom.
Klase
Postoji jedno pogrešno mišljenje na koje se može naići kada se radi sa TypeScriptom, a to je da je klase moguće opisati/definisati samo pomoću interfejsa.
Klasu je najnormalnije moguće definisati sa tipom.
Bilo koja od ove dvije opcije je validna.
Ukratko
Interfejs može definisati samo objekte, tip može objekte i sve ostalo.
Sintaksa za proširivanje, unije, utility tipove je mnogo bolja ako se koristi
type
alias.Interfejsi su otvoreni i podložni neželjenim izmjenama, dok su tipovi zatvoreni.
Nije tačno da se klase mogu definisati samo pomoću interfejsa. Klase bez problema mogu biti definisane tipom.
Posted on April 13, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 16, 2024
October 16, 2024