robotmayo
robotmayo

Reputation: 131

Class constructor and interfaces

How do I properly type Classes that implement interfaces?

Example code:

interface IPlugin{
  name:string;
}

class SomePlugin implements IPlugin{
  name;
  constructor(){
    this.name = 'Sam';
  }
}

const arrayOfClass:IPlugin = [SomePlugin];
// Ther error :
/*
Type 'typeof SomePlugin[]' is not assignable to type 'IPlugin'.
  Property 'name' is missing in type 'typeof SomePlugin[]'.
*/

How should I go about this?

Upvotes: 0

Views: 1620

Answers (1)

David Sherret
David Sherret

Reputation: 106650

Create an interface that describes objects that will instantiate objects that implement IPlugin. You can do this by using a new signature:

interface IPluginConstructor {
    new(...args: any[]): IPlugin;
}

Now type arrayOfClass as an array of IPluginConstructors:

const arrayOfClass: IPluginConstructor[] = [SomePlugin];

Note the [] in the type. That was absent in the question.

Sidenote

If you look closely, the type of name is any in SomePlugin... it's been set as any because the type was implicitly typed as any and string is assignable to any. That means the following code compiles:

const s = new SomePlugin();
const num: number = s.name; // this compiles... sad! :(

You should type that either explicitly...

class SomePlugin implements IPlugin {
  name: string;
  constructor() {
    this.name = 'Sam';
  }
}

...or implicitly...

class SomePlugin implements IPlugin {
  name = 'Sam';
}

I recommend you enable the noImplicitAny compiler flag to help catch these kind of mistakes in the future.

Upvotes: 3

Related Questions