pbanka
pbanka

Reputation: 726

When trying to use a subclass, getting a "Type 'typeof <Class>' is missing the following properties from type" error

Given the following code:

interface TaskInterface {
  execute(): Promise<any>;
}

class Task implements TaskInterface {
  private config: any = {};
  public constructor(config: any) {
    this.config = Object.assign({}, config);
  }
  public execute(): Promise<any> {
    return Promise.resolve(`Hi, Mom ${this.config.info}`);
  }
}

class Pop extends Task {
  public constructor(config: any) {
    super(config);
  }
}
class Fetch extends Task {}

const taskData = { type: "pop" };
let TaskClass: Task;
if (taskData.type === "pop") TaskClass = Pop;
if (taskData.type === "fetch") TaskClass = Fetch;
const configuration = { settings: { power: "full" } };
if (TaskClass) {
  const task = new TaskClass(configuration.settings);
  task.execute();
}

I am getting the following errors from TypeScript:

src/test.ts:24:42 - error TS2739: Type 'typeof Pop' is missing the following properties from type 'Task': config, execute
24 if (taskData.type === "pop") TaskClass = Pop;
    Did you mean to use 'new' with this expression?

src/test.ts:25:44 - error TS2739: Type 'typeof Fetch' is missing the following properties from type 'Task': config, execute
25 if (taskData.type === "fetch") TaskClass = Fetch;
  Did you mean to use 'new' with this expression?

src/test.ts:28:16 - error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
28   const task = new TaskClass(configuration.settings);
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I'm wondering what the proper way is to be able to implement this? Here is an online working example:

Upvotes: 2

Views: 857

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250036

The class name is the instance type, to get the type of the class itself you need typeof className:

const taskData = { type: "pop" };
let TaskClass: typeof Task;
if (taskData.type === "pop") TaskClass = Pop;
if (taskData.type === "fetch") TaskClass = Fetch;
const configuration = { settings: { power: "full" } };
if (TaskClass) {
    const task = new TaskClass(configuration.settings);
    task.execute();
}

Upvotes: 1

Related Questions