typescript - Er det mulig å få en funksjon til å akseptere klasseinstanser, men ikke akseptere vanlige objekter?
Jeg vil gjerne skrive en funksjon som tar klasseinstanser som parameter, men ikke tillater vanlige, anonymt typede objekter.
For eksempel:
class Dog {
constructor(name: string, breed: "husky" | "boxer") {
this.name = name;
this.breed = breed;
}
name: string;
breed: "husky" | "boxer";
}
class Cat {
constructor(name: string, breed: "siamese" | "persian") {
this.name = name;
this.breed = breed;
}
name: string;
breed: "siamese" | "persian";
}
function pat(pet: NoPlainObjects) {
document.write(pet.constructor.name);
}
pat(new Dog('Fido', 'boxer')); //works
pat(new Cat('Spot', 'persian')); //works
pat({name: 'snuffaluffagus'}); //compile error
Svar #1
Er det mulig å la en funksjon akseptere klasseinstanser, men ikke vanlige objekter?
Det er ikke mulig for øyeblikket, fordi TypeScript bruker strukturell sub-typing. Det betyr at et objekt opprettet med en klassekonstruktør er kompatibelt med en vanlig JavaScript-objektliteral når begge har kompatible egenskaper.
Her er hva dokumentasjonen sier om typekompatibilitet:
Den grunnleggende regelen for TypeScripts strukturelle typesystem er at x er kompatibel med y hvis y har minst de samme medlemmene som x. For å sjekke om y kan tildeles til x, sjekker kompilatoren hver egenskap til x for å finne en tilsvarende kompatibel egenskap i y... Den samme regelen for tildeling brukes når man sjekker argumenter ved funksjonskall. [uthevet lagt til]
Spørsmålet ditt reiser et spørsmål: hvorfor skulle du ønske at en funksjon skulle akseptere klasseinstanser og avvise vanlige gamle JavaScript-objekter?
Svar #2
Du kan bruke pipe-tegnet for å tillate forskjellige typer som argument for funksjonen din.
function pat(pet: Cat | Dog) {
document.write(pet.name);
}
