Sok fejlesztő összezavarodik, amikor egy TypeScript interfész vagy egy típus között választ. Ez valószínűleg azért van, mert nagyon hasonlóak, apró különbségekkel.
Vizsgáljunk meg néhány ésszerű gyakorlatot és alapértelmezést, miközben felfedezünk néhány rejtett gyöngyszemet a TypeScript nyelvben, és megválaszoljuk a kérdést: “Interfészeket vagy típusokat használjak?”
Ha befejezted, nézd meg a másik cikkemet a TypeScript Interfészek vs. osztályok témában!
Itt a szabályom: Olyan felhasználási esetekben, mint például új típusok létrehozása olyan dolgokon keresztül, mint a primitívek, union típusok és tuple típusok, inkább a type
kulcsszót használom. Minden máshoz (objektumok/táblák) interface
.
A interface
rendkívül hasznos, ha adatszerkezetekkel foglalkozunk, mivel ezek nagyon vizuálisan ábrázolják a dolgokat (bár a type
is az, jellemzően ezt preferálom). Teljesen rendben van, ha az objektumok és tömbök esetében is type
-t választasz.
Mindamellett, fedezzünk fel egy kicsit többet a Types vs Interfaces-ről a TypeScriptben, hogy megalapozottabb döntést hozhass.
Objects: Type vs Interface
Tipikusan egy adatszerkezetet definiálnánk egy típus modellezésére a tervezett változóinkkal és függvényargumentumainkkal szemben. Az adatszerkezet legtöbbször egy tömb vagy egy objektum, amely tartalmazhat néhány metódust.
Hozzunk létre egy objektumot interfészként (ajánlott megközelítés):
interface Milkshake { name: string; price: number; getIngredients(): string;}
Itt inkább interfészt használok, mert egyértelmű, hogy interfészről van szó, és nem egy változóról, amelyhez adatokat rendelünk – ez egy szép olvashatósági nyereség. A name
és price
segítségével rekordokat állíthatunk be, a getIngredients
pedig metódushívásként szolgál.
🎉 Töltse le ingyenesen!
Készen állsz arra, hogy túllépj a ForEach-en? Legyen magabiztos a fejlett módszerekkel – Reduce, Find, Filter, Every, Some és Map.
- Értse meg teljesen, hogyan kezelje a JavaScript adatszerkezeteket megváltoztathatatlan műveletekkel
- 31 oldal mélyreható szintaxis, valós példák, tippek és trükkök
- Írjon tisztább és jobban strukturált programozási logikát 3 óra alatt
Extra bónuszként néhány extra finomságot is küldünk neked néhány extra e-mailen keresztül.
Ha ezt egy típushoz hasonlítjuk – a =
:
type Milkshake = { name: string; price: number; getIngredients(): string;};
Ez csak az én kis preferenciám a interface
választása a type
használatával szemben itt – de nyugodtan használhatod a type
kulcsszót, ha akarod.
Kapcsolódás: Type vs Interface
Intersecting egyszerűen azt jelenti, hogy egy vagy több típust kombinálunk! Ez a minta megvalósítható mind egy interface
, mind egy type
használatával.
Tegyük fel a következő interfészeket, megmutatom, hogyan tudunk egy interface
és egy type
típusú interfészt keresztezni:
interface MilkshakeProps { name: string; price: number;}interface MilkshakeMethods { getIngredients(): string;}
Egy interfész esetében a extends
kulcsszó használatával kereszteznénk. Több interfészt használok, hogy megmutassam, hogyan bővíthetjük (örökölhetjük) egy végső Milkshake
interfészbe, amely tartalmazza az összes máshol definiált tulajdonságot és metódust:
// { name: string, price: number, getIngredients(): string }interface Milkshake extends MilkshakeProps, MilkshakeMethods {}
Az Milkshake
interfészt most már bárhol használhatjuk, és előnyünkre válhat, hogy name
, price
és getIngredients
egyetlen interfészhivatkozásban van.
Íme, hogyan csinálnánk ugyanezt egy type
-val és a típusok metszésével a &
segítségével:
// { name: string, price: number, getIngredients(): string }type Milkshake = MilkshakeProps & MilkshakeMethods;
Az interface
helyett egy type
használatát javaslom, ha típusokat akarunk metszeni. A extends
használata kicsit bőbeszédűbbnek és kevésbé áttekinthetőnek tűnik, és úgy érzem, hogy a type
kulcsszó erre készült.
Az is szuper egyszerű, hogy egyszerűen több típust kombináljunk a type
segítségével. Szerintem a kód áttekinthetőbb, mint a extends
használata az intefészekkel.
Az intefészek is korlátozottak – a type
alias használható összetettebb típusokhoz, mint például tuple, primitívek, unió és egyéb több:
// { name: string, price: number, getIngredients(): string }type Milkshake = MilkshakeProps & { getIngredients(): string };
Primitívek: Type vs Interface
Beszéljünk a primitív típusokról. Igen, karakterláncok, számok stb. Primitív típust csak type
aliashoz rendelhetsz:
type MilkshakeName = string;interface Milkshake { name: MilkshakeName; price: number;}
Ha primitív típust kell használnod, használj type
. Interfészek itt nem jöhetnek szóba egyetlen érték esetén, mivel a szintaxis nem támogatja.
🎉 Töltsd le ingyen!
Készen állsz arra, hogy túllépj a ForEach-en? Legyen magabiztos a fejlett módszerekkel – Reduce, Find, Filter, Every, Some és Map.
- Értse meg teljesen, hogyan kezelje a JavaScript adatszerkezeteket megváltoztathatatlan műveletekkel
- 31 oldal mélyreható szintaxis, valós példák, tippek és trükkök
- Írjon tisztább és jobban strukturált programozási logikát 3 óra alatt
Extra bónuszként néhány extra finomságot is küldünk neked néhány extra e-mailen keresztül.
A legtöbb esetben azonban egyszerűbb lenne közvetlenül a primitív értéket használni:
interface Milkshake { name: string; price: number;}
Ne bonyolítsd túl a kódodat! Type vs Interface
Függetlenül attól, hogy type
vagy interface
választottunk-e, a mód, ahogyan egy osztállyal használjuk, ugyanaz:
type Size = { size: string};interface Milkshake { name: string; price: number; getIngredients(): string;}class Order implements Size, Milkshake { // Size size = 'large'; // Milkshake name = 'Vanilla'; price = 399; getIngredients() { return ; }}
Az osztályok nem támogatják az union típusok implementálását/bővítését, mert statikus tervrajznak tekintik őket. Ez azt jelenti, hogy szuper explicitnek kell lennie minden egyes típusnak, amit implementál, mivel a TypeScript korlátai miatt jelenleg nem lehet dinamikus vagy változtatható.
Tudjon meg többet a TypeScript Interfaces vs Classes-ról!
Functions: Type vs Interface
Tipikusan én a type
alias használatával hoznék létre egy függvényt, mivel a legtöbbször egy anonim függvényt szeretnénk beírni:
type IngredientsFn = () => string;const getIngredients: IngredientsFn = () => ;
Ha azonban egy interface
használata ehhez inkább a te stílusod lenne, itt van, hogyan kell ezt megtenni:
interface IngredientsFn { () => string;}
Ez csak egy kicsit furcsának tűnik a type
használatához képest, de ismétlem, mindkettő teljesen érvényes TypeScript, és nincs különbség a kód lefordításakor.
Mikor ne használjunk Type
Most, miután megvizsgáltuk a különböző összehasonlításokat és ajánlott megközelítéseket, itt az ideje, hogy beszéljünk a Declaration Mergingről, a TypeScript egy olyan funkciójáról, amely csak a interface
-re vonatkozik, és egy ok lenne arra, hogy egy interface
-et válasszunk egy type
helyett.
A típusok type
használatával történő egyesítéséhez valami ilyesmit kellene tennünk, és létrehoznunk egy új végleges type
:
type MilkshakeProps = { name: string; price: number;};type MilkshakeMethods = { getIngredients(): string;};type Milkshake = MilkshakeProps & MilkshakeMethods;
A type Milkshake
típusunk most a MilkshakeProps
és a MilkshakeMethods
típus aliasának tekinthető. Megjegyezzük, hogy ennek a viselkedésnek az eléréséhez létre kellett hoznunk Milkshake
-t, így 3 egyedi típus alias-t kaptunk.
Az interfészeknél valójában van egy okosabb (egyesek szerint talán túl okos) megközelítés, amit deklarációs összevonásnak hívnak.
A deklarációs összevonást úgy érhetjük el, hogy egyszerűen kétszer deklaráljuk ugyanazt a interface
-t ugyanabban a hatókörben (ez történhet akár az interfész más modulból való importálásával, akár egy másik interfész mellett lokálisan deklarálva):
// declared once...interface Milkshake { name: string; price: number;}// declared again the same, it works!interface Milkshake { getIngredients(): string;}// { name: string, price: number, getIngredients(): string }const milkshake: Milkshake = { name: 'Banana', price: 399, getIngredients() {...}};
A Milkshake most már name
, price
és getIngredients
! A nyilatkozatok összevonása azonban jó dolog? Őszintén szólva nem vagyok a híve, és úgy érzem, hogy több kárt okozhat, mint hasznot. Én inkább a type
segítségével állítanám össze a típusokat, mintsem a deklarációs összevonást használnám – de legalább most már tudod a fő különbség(eke)t.
Következtetés
Ezzel meg is van! A Types és Interfaces közötti fő különbségek a TypeScriptben.
Összefoglalva, néhány személyes preferenciával is, én maradnék a interface
-nél az objektumok esetében, és a type
alias kulcsszót használnám az új típusok menet közbeni összeállításához. Ezek az új típusok akár interfészekből vagy más típusokból, például tuple-okból, unióból és metszet típusokból is származhatnak. Rengeteg lehetőség van, de a megközelítések megértésével elkezdhetjük kiválasztani a megfelelő eszközt.
A legtöbb esetben az interfészek és a típusok nagyjából ugyanazok, néhány itt tárgyalt különbségtől eltekintve. Remélem, élvezted az olvasást!
Ha komolyan gondolod a TypeScript készségeidet, a következő lépésed, hogy vess egy pillantást a TypeScript tanfolyamaimra, ezek részletesen megtanítanak a teljes nyelvi alapokra, valamint számos haladó felhasználási esetre, amire szükséged lesz a mindennapi TypeScript fejlesztés során!
Boldog kódolást!