The interface declares the method/members the instances must have, not including what the implementing class has.
For example check the Array and ArrayConstructor declarations:
interface Array<T> { length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T | undefined; ... [n: number]: T; } interface ArrayConstructor { new (arrayLength?: number): any[]; new <T>(arrayLength: number): T[]; new <T>(...items: T[]): T[]; (arrayLength?: number): any[]; <T>(arrayLength: number): T[]; <T>(...items: T[]): T[]; isArray(arg: any): arg is Array<any>; readonly prototype: Array<any>; }
As you can see, the Array has method/members which exist on any instance of array:
let a = []; a.push(1, 2, 3); console.log(a.length);
But the ArrayConstructor has the members/methods which exist on the Array itself:
console.log(Array. prototype); console.log(Array.isArray(9));
The constructors are part of the "static" part which is why they are declared in the ArrayConstructor.
If you declare a constructor on an interface for example you'll have a problem implementing that interface:
interface MyInterface { constructor(); getName(): string; } class MyClass implements MyInterface { constructor() {} getName() { return "name" }; }
Error:
Class 'MyClass' incorrectly implements interface 'MyInterface'. Types of property 'constructor' are incompatible. Type 'Function' is not assignable to type '() => void'. Type 'Function' provides no match for the signature '(): any'.