typescript - Är det möjligt för en funktion att acceptera klassinstanser, men inte acceptera vanliga objekt?
Jag skulle vilja skriva en funktion som tar klassinstanser som parameter, men inte tillåter vanliga, anonymt typade objekt.
Till exempel:
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
Är det möjligt att låta en funktion acceptera klassinstanser, men inte acceptera vanliga objekt?
Det är för närvarande inte möjligt, eftersom TypeScript använder strukturell subtypning. Det det betyder är att ett objekt som skapats med en klasskonstruktör är kompatibelt med ett vanligt gammalt JavaScript-objektliteral när båda har kompatibla egenskaper.
Här är vad dokumentationen säger om typkompatibilitet:
Den grundläggande regeln för TypeScripts strukturella typ system är att x är kompatibel med y om y har minst samma medlemmar som x. För att kontrollera om y kan tilldelas x, kontrollerar kompilatorn varje egenskap hos x för att hitta en motsvarande kompatibel egenskap i y... Samma regel för tilldelning används när man kontrollerar argument vid funktionsanrop. [betoning tillagd]
Din fråga väcker en fråga: varför skulle du vilja att en funktion accepterar klassinstanser och avvisar vanliga JavaScript-objekt?
Svar #2
Du kan använda pipen för att tillåta olika typer som argument till din funktion.
function pat(pet: Cat | Dog) {
document.write(pet.name);
}
