Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript "extends" generic constraint

I am using the extends constraint in TypeScript, like so:

class Animal {}
class Lion extends Animal {}
class Bear extends Animal {}

class ZooKeeper<T extends Animal> {
    constructor(p: T = new Animal()) {

    }
}

new ZooKeeper(new Animal());

But p: T = new Animal() contains an error:

Type 'Animal' is not assignable to type 'T'.

constructor Animal(): Animal

Why, and what do I do, in order that I can use Animal, in place of Animal subtypes?

Source

like image 919
Matthew Layton Avatar asked Oct 05 '16 11:10

Matthew Layton


2 Answers

Cast your animal to T and it will work.

class ZooKeeper<T extends Animal> {
    constructor(p: T = <T>new Animal()) {

    }
}

According to your own comment (for future readers) you can also do:

class ZooKeeper<T extends Animal> {
    constructor(p: T = new Animal() as T) {

    }
}
like image 120
Hampus Avatar answered Nov 06 '22 21:11

Hampus


You could just leave the assignment from the constructor parameter declaration, seems to be compiling properly for me. You can even make the parameter optional, if you may want to leave it.

UPDATE: As series0ne pointed out, this solution does not provides a default instance of Animal where one has not been provided!

class ZooKeeper<T extends Animal> {
    constructor(p?: T) {
    }
}

var zk = new ZooKeeper<Lion>(new Lion());
var zk2 = new ZooKeeper(new Animal());
var zk3 = new ZooKeeper();

The ZooKeeper class will be typed and you can access the child class specific properties of T.

like image 2
ther Avatar answered Nov 06 '22 22:11

ther