How does typescript interact with designed signatures?

I'm having problems with how designers work in interfaces. Perhaps I don’t understand anything at all. But I was looking for answers for a while, and I can not find anything related to this.

How to implement the following interface in a TypeScript class:

interface MyInterface { new ( ... ) : MyInterface; } 

Anders Halesberg creates an interface containing something similar to this video (approximately 14 minutes). But for the life of me I cannot realize this in the classroom.

I probably misunderstand something that I won’t get?

EDIT:

To clarify. With "new (...)" I meant "anything." My problem is that I cannot get even the most basic version of this work:

 interface MyInterface { new () : MyInterface; } class test implements MyInterface { constructor () { } } 

This is not a compilation for me. I get a "Class Test" declaring the "MyInterface" interface but not implementing it. The type "MyInterface" requires a construction signature, but when you try to compile it, the type "test" is missing. "

EDIT:

So, after learning this a bit more, given the feedback.

 interface MyInterface { new () : MyInterface; } class test implements MyInterface { constructor () => test { return this; } } 

TypeScript is not valid and this does not solve the problem. You cannot determine the return type of the constructor. He will return the "test". Signature: class test {constructor () {}} This seems to be a "new () => test" (obtained by hovering over the "class" in the online editor using only the code that is inserted). And this is what we would like and what I thought it would be.

Can someone provide an example of this or something similar where it actually compiles?

EDIT (again ...):

So, I could come up with why this can be defined in the interface, but not possible to implement in the TypeScript class. The following works:

 var MyClass = (function () { function MyClass() { } return MyClass; })(); interface MyInterface { new () : MyInterface; } var testFunction = (foo: MyInterface) : void => { } var bar = new MyClass(); testFunction(bar); 

So, is this just a TypeScript function that allows you to interact with javascript? Or can you implement it in TypeScript without having to implement the class using javascript?

+135
javascript constructor interface typescript
Nov 15 '12 at 22:03
source share
4 answers

Building signatures in interfaces is not implemented in classes; they are only intended to define existing JS APIs that define a "new" function. Here is an example containing the new interfaces that work:

 interface ComesFromString { name: string; } interface StringConstructable { new(n: string): ComesFromString; } class MadeFromString implements ComesFromString { constructor (public name: string) { console.log('ctor invoked'); } } function makeObj(n: StringConstructable) { return new n('hello!'); } console.log(makeObj(MadeFromString).name); 

This creates an actual limitation for what you can call makeObj with:

 class Other implements ComesFromString { constructor (public name: string, count: number) { } } makeObj(Other); // Error! Other constructor doesn't match StringConstructable 
+139
Nov 15 '12 at 23:26
source share

In my search for exactly the same question, I went to see how TypeScript -Team did it ...

They declare an interface, and then a variable with a name corresponding to the exact name of the interface. It is also a way to introduce static functions.

Example from lib.d.ts :

 interface Object { toString(): string; toLocaleString(): string; // ... rest ... } declare var Object: { new (value?: any): Object; (): any; (value: any): any; // ... rest ... } 

I tried this and it works like a charm.

+54
Dec 04 '12 at 10:35
source share

From a design point of view, it is usually not necessary to specify requirements for a designer in an interface. The interface should describe the operations that you can perform on the object. For different classes that implement the interface, they must be allowed to require different constructor parameters if they need to.

For example, if I had an interface:

 interface ISimplePersistence { load(id: number) : string; save(id: number, data: string): void; } 

I can have implementations for storing data in the form of a cookie, which does not require constructor parameters, and a version that stores data in a database, which requires a connection string as a constructor parameter.

If you still want to define constructors in the interface, there is a dirty way to do this, which I used to answer this question:

Interfaces with design signatures are not type-checked

+3
Nov 15 '12 at 23:15
source share

You can use Decorators to achieve the intended behavior, although this is probably not what they should be used for.

it

 interface MyInterface { new (); } function MyInterfaceDecorator(constructor: MyInterface) { } @MyInterfaceDecorator class TestClass { constructor () { } } 

compiles without problems. In contrast, the following definition for TestClass

 // error TS2345: Argument of type 'typeof TestClass' is not assignable to parameter of type 'MyInterface'. @MyInterfaceDecorator class TestClass { constructor (arg: string) { } } 

will not compile.

+2
Jul 21 '16 at 21:09
source share



All Articles