Theodore Norvell
Theodore Norvell

Reputation: 16231

Requiring argument to be an instance of a (sub)class of a given class in typescript

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 Chickens 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

Answers (1)

jeremyalan
jeremyalan

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

Related Questions