Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interfaces with construct signatures not type checking

Tags:

typescript

I've been playing a bit with interfaces with construct signatures in TypeScript, and I became a bit confused when the following failed to type check:

class Foo {
    constructor () {
    }
}

interface Bar {
    new(): Bar;
}

function Baz(C : Bar) {
    return new C()
}

var o = Baz(Foo);

The type error is:

Supplied parameters do not match any signature of call target: Construct signatures of types 'new() => Foo' and 'Bar' are incompatible: Type 'Bar' requires a construct signature, but Type 'Foo' lacks one (C: Bar) => Bar

The type of Foo's constructor is () => Foo, and that is what I thought that Bar said. Am I missing something here?

like image 228
farre Avatar asked Oct 18 '12 10:10

farre


People also ask

CAN interface have constructor TypeScript?

Benefits to using TypeScript interface constructors With a constructor on the interface, you can specify that all of your types must have certain methods/properties (normal interface compliance) but also control how the types get constructed by typing the interface like you would with any other method/property.

What is construct signature?

So an interface with a construct signature defines the signature of a constructor! The constructor of your class that should comply with the signature defined in the interface(think of it as the constructor implements the interface). It is like a factory!

What is the difference between interface and type in TypeScript?

// One major difference between type aliases vs interfaces are that interfaces are open and type aliases are closed. This means you can extend an interface by declaring it a second time. // In the other case a type cannot be changed outside of its declaration.

How do you pass an interface as a parameter TypeScript?

An interface type cannot be passed as a parameter. When running TypeScript code, you are really compiling it down to JavaScript and then running the JavaScript. An interface is a TypeScript compile-time construct, so at runtime, there is no such thing as an interface type to call functions on or inspect properties of.


2 Answers

Here is an updated version of your code with a subtle change.

We define the Bar interface with whatever functions and variables we expect to be present.

Next, we extend the Bar interface with the NewableBar interface. This just defined a constructor that returns a Bar.

Because Foo implements Bar and has a constructor and Baz requires a NewableBar, everything is checked.

This is a little more verbose than any - but gives you the checking you want.

interface Bar {

}

interface NewableBar extends Bar {
    new();
}

class Foo implements Bar {
    constructor () {

    }
}

function Baz(C : NewableBar) {
    return new C()
}

var o = Baz(Foo);
like image 137
Fenton Avatar answered Sep 20 '22 20:09

Fenton


The problem (at least from the TypeScript compiler's point of view) is the signature of Bar's new method. If you replace the definition of Bar with the following,

interface Bar {
  new (): any;
}

it works. You might as well use new (): Foo, just Bar as return value does not work.

like image 24
Adrian Heine Avatar answered Sep 22 '22 20:09

Adrian Heine