2

I am trying to write a compact typescript definition file, but I am having troubles doing so for a larger project.

My project has lots of interfaces that are implemented by a number of classes.

From what I can see I always need to re"implement"/redeclare the methods of the interfaces in the classes like so:

declare module someModule {

    interface InterfaceOne {
        /**
        * Some lengthy description
        */
        someStuff():any;
        /**
        * Some lengthy description
        */
        moreStuff():any;
    }

    class OneClass implements InterfaceOne {
        /**
        * Some lengthy description
        */
        someStuff():any;
        /**
        * Some lengthy description
        */
        moreStuff():any;
        /**
        * Even more description
        */
        classStuff(): any;
    }

    class TwoClass implements InterfaceOne {
        /**
        * Some lengthy description
        */
        someStuff():any;
        /**
        * Some lengthy description
        */
        moreStuff():any;
        /**
        * Even more description
        */
        classStuff(): any;
    }
}   

If I leave out the someStuff and moreStuff declarations from the interfaces I get this error:

error TS2137: Class TwoClass declares interface InterfaceOne but does not implement it:

So I always need to copy all of the declarations to each and every class that implements the interface.

Is there some way around that? Why do I need to do that? Is there any good reason for having to copy the combined contents of all interfaces to the class bodies in a library declaration file? It's a declaration only, not the implementation, so why isn't my declaration implements InterfaceOne enough already? I don't need to copy all base type members from a super type to an extending type, either, so why is this different for interfaces?

In the library that I am writing the definition file for these interfaces are actually mixins so in the end my definition file actually gets longer than the original implementation that has the bodies!

Edit: After posting I found this answer - so my question is likely to be a duplicate, although the other question is for a far older version of Typescript.

Edit: I realize this may not be the correct place to discuss this and I am thinking about deleting this question. For reference, I asked the question in this official typescript issue.

Community
  • 1
  • 1
Sebastian
  • 7,729
  • 2
  • 37
  • 69

2 Answers2

0

EDITED

declare module someModule {

    interface InterfaceOne {
        /**
         * Some lengthy description
         */
        someStuff():any;
        /**
         * Some lengthy description
         */
        moreStuff():any;
    }

   interface OneClass extends InterfaceOne {
       new(): OneClass;
       /**
         * Even more description
         */
        classStuff(): any;
   }

   interface TwoClass extends InterfaceOne {
       new(): TwoClass;
       /**
         * Even more description
         */
        classStuff(): any;
   }

}

(did this in a bus, needs more checking)

Bruno Grieder
  • 28,128
  • 8
  • 69
  • 101
  • Thanks, but another more crucial problem is this means `OneClass` and `TwoClass` can not extend from another (possibly different) class anymore. And that's what interfaces are for - to be implemented by different/unrelated classes. My library is pure Javascript and even without the duplication the .d.ts file is 8MB in size, so even if created automatically it would still be huge. – Sebastian Oct 30 '15 at 13:46
  • OK. There is a "pure" interface solution to describe this using a Factory for the constructor and variables. It is bit convoluted but when I have a few minutes I will try to edit the answer – Bruno Grieder Oct 30 '15 at 14:09
  • Completely edited my answer. Yup... Class Interfaces. Check this : http://stackoverflow.com/questions/13407036/how-does-typescript-interfaces-with-construct-signatures-work – Bruno Grieder Oct 30 '15 at 14:36
  • Thanks for your efforts, unfortunately this is the situation that I *have* already (the 8 MBs) and that I am trying to get away from. Because if I model everything with interfaces, this is works, but having no classes means no one can extend my classes anymore properly. I want to model my library as precisely as possible to get the most out of typescript. No classes means no subclassing :-( – Sebastian Oct 31 '15 at 08:49
  • OK never mind but for the sake of the argument: you do not *have* this situation: there is no duplication is my example and I do not get your argument about subclassing: this is just a definition file, and you can always extend an interface (modeling a class) – Bruno Grieder Oct 31 '15 at 08:57
  • Mmmh - here is what I want to be able to do ultimately: Can you get this to work with your ideas? Define an interface, let a class implement that interface and have the client (the consumer of the d.ts file) be able to extend that class and override one of the interface members and call super()? I may be blind or incapable but I just can't get this to compile. – Sebastian Oct 31 '15 at 10:27
0

Have you tried interface/class merging?

https://www.typescriptlang.org/docs/handbook/declaration-merging.html

export interface Foo {
    bar: string;
}

export class Foo {
    constructor() { this.bar = 'foobar'; }
}

export interface AnotherFoo extends Foo {}

export class AnotherFoo {
    foo = 'bar'; // add a foo member only to this class
}
Simon Hänisch
  • 4,740
  • 2
  • 30
  • 42