Reputation: 16231
The following compiles without error in TypeScript
abstract class Animal {
abstract talk() : string ;
}
class Chicken extends Animal {
talk() : string { return "cluck" ; }
}
class Duck extends Animal {
talk() : string { return "quack" ; }
}
function quack( d : Duck ) {
console.log( d.talk() ) ;
}
var a = new Chicken() ; // EDIT: `var a : Chicken = new Chicken()` gives the same result
quack( a ) ;
What I would like to do is to change the definitions Chicken
and Duck
or maybe quack
in a way such that quack(a)
has a compile time error. I.e. parameter d
of type Duck
should not be able to hold Chicken
s nor any other objects that aren't direct or indirect instances of Duck
. I know that I can add unique properties to Chicken
and Duck
to distinguish them. E.g.
class Duck extends Animal {
onlyInDuck : string ;
talk() : string { return "quack" ; }
}
class Chicken extends Animal {
onlyInChicken : string ;
talk() : string { return "cluck" ; }
}
But this seems like a crude hack.
Is there an elegant way to require that a function argument be an instance of a (sub)class of the parameter type?
Upvotes: 2
Views: 73
Reputation: 4786
I could be wrong here, but I'm guessing probably not. This appears to be by design to make the TypeScript language easier to interop with existing JavaScript code, as well as to embrace the dynamic nature of the language.
More specifically, since JavaScript (and by extension, TypeScript) doesn't actually have "types" (in the classical sense), the TypeScript compiler is more concerned about whether or not a particular instance adheres to a particular interface, with the same properties, functions, etc. as opposed to whether or not it was created using a particular constructor.
For your sake, I hope I'm wrong, but it wouldn't surprise me either way.
Upvotes: 2