Search code examples
javascripttypescripttypescript-definitions

Typescript definition for a class as an object property


I'm putting together a quick .d.ts for a library, but have hit a snag with the following:

class Issuer {
    constructor(metadata) {
        // ...
        const self = this;
        Object.defineProperty(this, 'Client', {
            value: class Client extends BaseClient {
                static get issuer() {
                    return self;
                }
                get issuer() {
                    return this.constructor.issuer;
                }
            },
        });
    }
    // ...
}

This is used from the user facing API as such (with googleIssuer being an instance of Issuer).

const client = new googleIssuer.Client({
    // ...
})

I've tried extending the Issuer class definition with a namespace with the same name, but this doesn't behave as I had hoped.

What would be the simplest way to represent this in my definition?


Solution

  • Using class and namespace merging you get the equivalent of a static class (a class that can be accessed using the class, not an instance of a class):

    declare class Issuer {
    
    }
    
    declare namespace Issuer {
        class Client{}
    }
    declare class GoogleIssuer extends Issuer {
    }
    let d = new GoogleIssuer.Client() // Ok
    let googleIssuer = new GoogleIssuer();
    let c = new googleIssuer.Client() // error
    

    What you want is a class definition that is tied to an instance on the class. For this you can just declare the class as a field of the Issuer class:

    // Declare the structure of client separately 
    declare class Client {
    
    }
    declare class Issuer {
        Client: typeof Client; // Declare a field that is of the class type
    }
    declare class GoogleIssuer extends Issuer {
    }
    let googleIssuer = new GoogleIssuer();
    let c = new googleIssuer.Client() // ok