Mark Vincze
Mark Vincze

Reputation: 8043

How to define an interface which matches certain type objects?

In a piece of code I'd like to do a sort of metaprogramming, and I want to define a function to which I can pass in certain types as arguments (so not instances of a type, but the types themselves).

And I want to restrict the accepted types to be a certain class or its descendants.

I'm trying to achieve this with the following code:

class ABase {}
class AConc extends ABase {}

class B {}

interface IAClass {
  new(): ABase;
}

function meta(AT: IAClass) {
  console.log('foo');
}

// This gives an error, as it should.
meta(5);

// These compile, this is the usage I want.
meta(ABase);
meta(AConc);

// These compile, but this is what I don't want to allow.
// I only want to be able to pass in types deriving from ABase.
meta(B);
meta(Array);
meta(Number);

The first call, meta(5) gives me a compiler error, rightfully so. On the other hand, the last 3 calls compile without any errors, despite that the types passed in are not deriving from ABase.

What am I doing wrong? Is there a way to achieve this?

Upvotes: 2

Views: 47

Answers (1)

cevek
cevek

Reputation: 862

You want nominal typing, but it is not supported yet by typescript.

Typescript team recommends to use __brand field on your classes:

class ABase {private __brand: ABase}

Upvotes: 2

Related Questions