2

I'm reading the Class Types section of the Typescript Handbook and I'm confused about how to write the interface definition for a Class. From the documentation, I understand that an interface can be used to describe the "instance" side of the Class. But how would you write the interface that describes the "static" side of the Class?

Here's an example:

interface IPerson {
    name: string;
    getName(): string;
}

class Person implements IPerson {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    public getName() {
        return this.name;
    }
}

In this example, how would you modify IPerson so that the constructor function can also be described as well?

wmock
  • 5,382
  • 4
  • 40
  • 62

3 Answers3

6

You can create a separate interface for your static needs:

interface IPerson {
    name: string;
    getName(): string;
}

class Person implements IPerson {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    public getName() {
        return this.name;
    }

    public static create(name: string) { // method added for demonstration purposes
        return new Person(name);
    }
}

Static interface:

interface IPersonStatic {
    new(name: string); // constructor
    create(name: string): IPerson; // static method
}

let p: IPersonStatic = Person;

Also, you can use typeof to determine the type:

let p2: typeof Person = Person; // same as 'let p2 = Person;'
let p3: typeof Person = AnotherPerson;
zlumer
  • 6,844
  • 1
  • 25
  • 25
  • Can you explain what `let p: IPersonStatic = Person` means? Is this setting the `p` variable to be referencing the `Person` class? – wmock Jun 25 '16 at 13:42
  • 2
    @wmock The `Person` class declaration creates two things both called `Person` - 1) a type and 2) a variable that refers to a function that constructs a `Person` (and should be called with the `new` prefix, i.e. a constructor). There's no problem with them getting confused because in TS your code is always definitely talking about either types or values but not both. So the variable `Person` is like a `const` of type `Person`, and can be assigned to any variable of a structurally compatible type. – Daniel Earwicker Jun 25 '16 at 22:22
0

I added IPersonConstructor to your example. The rest is identical; just included for clarity.

new (arg1: typeOfArg1, ...): TypeOfInstance; describes a class, since it can be invoked with new and will return an instance of the class.

interface IPerson {
    name: string;
    getName(): string;
}

class Person implements IPerson {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    public getName() {
        return this.name;
    }
}

interface IPersonConstructor {
    // When invoked with `new` and passed a string, returns an instance of `Person`
    new (name: string): Person;
    prototype: Person;
}
cspotcode
  • 1,832
  • 1
  • 13
  • 17
0

How about a generic

interface IConstructor<T> extends Function {
    new (...args: any[]): T;
}
codeBelt
  • 1,727
  • 16
  • 22