TypeScript-interfaces: van syntaxis tot interface vs type
TypeScript-interfaces
TypeScript-interface: syntaxis, extends, merging, vs type | We.Inc
Bouw een interface veld voor veld, zie de bijpassende type alias, en leer optionele en readonly members, extends, declaration merging en wanneer een type alias beter past.
Een interface geeft de vorm van een object een naam: welke properties het heeft en welk type elk ervan bevat. Maak een property optioneel met ? en onveranderlijk met readonly, bouw voort op een andere vorm met extends, en open dezelfde naam opnieuw om er meer members in samen te voegen. Interfaces laten geen spoor na in het gecompileerde JavaScript; ze sturen alleen de checker.
Interface-syntaxis in één oogopslag
U wilt
Schrijf
Een verplichte property
name: string;
Een optionele property
nickname?: string;
Een property die niet opnieuw toegewezen kan worden
readonly id: number;
Een methode
greet(other: User): string;
Een willekeurig aantal string-keys
[key: string]: number;
Een andere vorm hergebruiken
interface Admin extends User { ... }
Meerdere vormen combineren
interface A extends B, C { ... }
Voeg velden toe in de builder hieronder, vink optioneel of readonly aan, en kopieer de interface of de gelijkwaardige type alias. De secties daaronder behandelen extends, merging en de paar gevallen waarin de keuze tussen interface en type er echt toe doet.
Geef de interface een naam en typ, als hij voortbouwt op een andere, die naam in het extends-veld.
Voeg per property een rij toe en kies het type en of hij optioneel of readonly is.
Lees de interface en de type alias die de builder uit dezelfde rijen schrijft.
Kopieer een van beide versies naar uw code.
Begin met interface voor objectvormen en kies type als u een union, een tuple of een mapped type nodig hebt. Dat is de vuistregel die het TypeScript-handboek zelf voorstelt.
readonly voorkomt alleen het opnieuw toewijzen van die ene property. Objecten die erin genest zijn kunnen nog steeds veranderen, en er wordt niets afgedwongen tijdens runtime.
Een optionele property leest als haar type of undefined, dus controleer haar voor gebruik of geef haar een standaardwaarde bij het destructureren.
Houd interfacenamen enkelvoudig en beschrijvend, zoals Invoice of CartItem. Een voorvoegsel zoals IInvoice voegt niets toe wat de editor u niet al vertelt.
Veelgestelde vragen
Moet ik interface of type gebruiken?
Voor objectvormen werken beide en het handboek noemt het grotendeels persoonlijke voorkeur, met het advies interface te gebruiken totdat u een functie nodig hebt die alleen type heeft. Gebruik type voor unions, tuples, primitives en mapped of conditional types; gebruik interface als u declaration merging wilt.
Wat is declaration merging?
Een interface declareren met een naam die al bestaat, voegt er members aan toe in plaats van een fout te geven. Libraries leunen hierop zodat u hun types kunt uitbreiden, bijvoorbeeld door een property aan Window toe te voegen. Een type alias met een herhaalde naam is een fout.
Wat gebeurt er als twee samengevoegde interfaces een property verschillende types geven?
De compiler meldt een fout. Bij een intersectie van twee types wordt het conflict niet bij de declaratie gemeld; de property wordt never, wat pas later aan het licht komt en moeilijker te herleiden is.
Kan een interface een functie of een array beschrijven?
Ja. Een call signature zoals (value: string): boolean beschrijft een functie, en een index signature zoals [index: number]: string beschrijft een array-achtig object. Voor eenvoudige gevallen leest een type alias zoals type Check = (v: string) => boolean duidelijker.
Bestaan interfaces tijdens runtime?
Nee. Ze compileren naar niets, dus u kunt geen instanceof gebruiken met een interface of de keys ervan opsommen. Controleer waarden met een runtime guard en annoteer het returntype daarvan met de interface.
extends tegenover intersecties
interface Bear extends Animal kopieert elke member van Animal en laat u er meer aan toevoegen. Een type alias doet hetzelfde met een intersectie, type Bear = Animal & { honey: boolean }.
Het handboek merkt op dat extends sneller kan zijn voor de compiler en conflicterende members meldt precies waar ze gedeclareerd zijn. Intersecties zijn handig om vormen aan elkaar te plakken die u niet zelf beheert.
Optioneel, readonly en index signatures
Een vraagteken na de naam maakt een property optioneel, en het leestype ervan bevat undefined. readonly blokkeert toewijzing aan die property na het aanmaken, maar is alleen een controle tijdens het compileren.
Een index signature, [key: string]: number, beschrijft dictionaries waarvan u de keys niet vooraf kunt opsommen. Benoemde properties in dezelfde interface moeten passen bij het waardetype van de index signature.
Merging om globale en library-types uit te breiden
Omdat interfaces samenvoegen, kan een declaratiebestand uw eigen velden toevoegen aan ingebouwde vormen. Een veelvoorkomend geval is Window een property geven die een script instelt, zodat het lezen ervan zonder cast door de typecheck komt.
interface vs type alias
Wat elke declaratie kan
Functie
type alias
Een objectvorm beschrijven
Ja
Ja
Members toevoegen door de naam opnieuw te declareren
Ja (merging)
Nee, fout over dubbele identifier
Voortbouwen op een andere vorm
Intersectie met &
Union van vormen of literals
Nee
Ja
Een primitive of tuple een naam geven
Nee
Ja
Mapped en conditional types
Nee
Ja
Patronen die u vaak zult schrijven
Eén en meerdere interfaces uitbreiden
Admin krijgt elke member van User plus zijn eigen; Card combineert twee ongerelateerde vormen.
Declaration merging op Window
In een .d.ts-bestand gezet, zorgt dit dat window.appVersion overal door de typecheck komt.
Index signature en call signature
Scores accepteert elke string-key; Validator beschrijft een aanroepbare waarde.
Interface-builder
Naam van de interface
Extends (optioneel)
Naam van property {n}
Type van property {n}
Optioneel
Readonly
Property {n} verwijderen
Property toevoegen
Als interface
Als type alias
Interface kopiëren
Type kopiëren
Namen moeten beginnen met een letter, $ of _ en mogen alleen letters, cijfers, $ of _ bevatten.