Hannes Petri
Hannes Petri

Reputation: 874

Type signifying "this very class" in TypeScript

I want to create a one-argument method where the rhs can only be of the exact same type as the lhs – not any of its superclasses or subclasses. What's the right type to use?

The following code illustrates what I want to achieve. For the purpose of this question, I used self but I suspect that it means something else.

abstract class Animal {
    public mateWith(animal: self): void {
        // ...          HERE ⤴️
    }
}

class Dog extends Animal {}
class Cat extends Animal {}
class Tiger extends Cat {}

const dog1 = new Dog();
const dog2 = new Dog();
const cat = new Cat();
const tiger = new Tiger();    

dog1.mateWith(dog2); // Valid
dog1.mateWith(cat); // Invalid
cat.mateWith(tiger); // Also invalid

Upvotes: 2

Views: 58

Answers (1)

k0pernikus
k0pernikus

Reputation: 66718

Instead of self you want this for the actual abstract class name.


I don't know if it's possible to dynamically check for the subclass and I suspect you'll want to have it be invalid on compile-time.

Yet as a workaround you'll could make do with a run-time check via the help of the constructor name:

abstract class Animal {
    public mateWith(animal: this): string {
        const msg = `${animal.constructor} with: ${this.constructor}, that: `;

        if (animal.constructor !== this.constructor) {
            return msg + "WON'T work!".trim() + "\n";
        }

        return msg + "works!".trim() + "\n";
    }
}

class Dog extends Animal {
}

class Cat extends Animal {
}

class Tiger extends Cat {
}

const dog1 = new Dog();
const dog2 = new Dog();
const cat = new Cat();
const tiger = new Tiger();

console.log(
    dog1.mateWith(dog2),
    dog1.mateWith(cat),
    cat.mateWith(tiger),
);

It will output:

class Dog extends Animal {
} with: class Dog extends Animal {
}, that: works!
 class Cat extends Animal {
} with: class Dog extends Animal {
}, that: WON'T work!
 class Tiger extends Cat {
} with: class Cat extends Animal {
}, that: WON'T work!

Upvotes: 1

Related Questions