reactjstypescripttypesreact-server

Adding TypeScript definitions for wrapped classes


I'm using a package called react-server that can take any class and will add methods to it at runtime. It expects to have the class that it wraps to have an interface like

interface {
    getElements(): Array<React.Component>
}

and it will add methods to the class like getRequest(), which can be referenced from inside the class as well.

Imagine a page class like:

class SimplePage {
  getElements() {
    // Right now, this wouldn't compile, because this.getRequest() is
    // not an available method.
    const request: Request = this.getRequest();
    // ...
  }
}

Given that this.getRequest() doesn't actually exist at compile time, and that react-server doesn't actually provide any real classes or interfaces that I can reference from my definition file, is there any way that I can create a definition that I can use that calls out that something is, in fact, a Page type and has these methods available to it?

Ideally, I'd love to be able to provide these in a definition file (.d.ts) somewhere so that I can reference them in any app that uses react-server. I'd also love to do this without being forced to cast this to something else every time I wanted to reference the method.


Solution

  • You have 2 options that I can think of.
    Given the following interface:

    interface ExtendedPage {
        getRequest(): Request;
    }
    

    (1) The this parameter:

    class SimplePage {
        getElements(this: SimplePage & ExtendedPage) {
            const request: Request = this.getRequest();
            // ...
        }
    }
    

    (2) Implement the interface with stand-in properties (like with mixins):

    class SimplePage implements ExtendedPage {
        getElements() {
            const request: Request = this.getRequest();
            // ...
        }
    
        getRequest: () => Request;
    }
    

    Edit

    You can declare a class and extend it:

    declare class ExtendedPage {
        getRequest(): Request;
    }
    
    class SimplePage extends ExtendedPage {
        ...
    }