krojew krojew - 3 months ago 31
Javascript Question

TypeScript: extending existing JavaScript object

I have a pure JavaScript object (let's call it O) from a certain library, with its interface in an ambient namespace, e.g.:

declare namespace N {
interface IO {
// properties...
}
}


I need to create a TypeScript class, which will extend this JavaScript object. The mechanism for extending it is provided by the library, so I cannot use the native TS inheritance, yet I need to have access to all the properties of this JS object, which I'm extending. I tried declaring a class which implements this interface and extending it:

declare class DummyO implements N.IO {
// copy-paste everything from N.IO
}

class MyRealClass extends DummyO {
}


Now I have access to all the properties, but also two problems:


  1. I had to copy-paste the whole interface, which is not so practical.

  2. TypeScript doesn't create any definition for DummyO (which is good), but in the same time tries to extend it using its native mechanism (which is bad, since DummyO doesn't really exist).



So the question is - how to work around it? How to create a TS class, which effectively extends this native object? Or maybe there's another way to convince TS that I'm really inheriting O without all that hassle?

Answer

The only working solution I know of is pretty much copy-pasting the interface into the class:

declare namespace N {
    interface IO {
        // example properties:
        a: number;
        f(): number;
    }
}


class MyRealClass implements N.IO {
    // copy IO
    a: number;
    f: () => number;

    // add "real" members later...
}

It isn't pretty, but that's what you get with custom inheritance solutions in libraries.