how to implement an abstract class with static properties in typescript

1.4k Views Asked by At

I am creating a job system and I want my DSL to look like the following:

@ScheduledTaskProcessor()
export class ScoringProcessor extends AbstractScheduledProcessor<ScoringInput> {

  static cron = CRON_NIGHTLY_FIRST_BATCH

  async process(args: ScoringInput) {
     // does some work
  }
}

i would love AbstractScheduledProcessor to look like the following:

export abstract class AbstractScheduledProcessor<T> {

  abstract static cron: string;

  abstract process(args: T): Promise<void>

  ... other non abstract method follow ...

but i get: TS1243: 'static' modifier cannot be used with 'abstract' modifier.

Can anyone suggest a path forward. Perhaps I can use my class decorator as a HOF to create the class with the static property.

FYI my ScheduledTaskProcessor decorator function curently looks like this:

import { Container } from 'typedi'


export function ScheduledTaskProcessor(): ClassDecorator {

  return function(target) {
    console.log('registering: ', target)
    Container.of('ScheduledTaskProcessor').set(target.name, target)
  }

}
1

There are 1 best solutions below

1
On BEST ANSWER

You can make sure that you have to set a static value with decorators. The approach would look like this:

// This interface represents the type of an uninstantiated class, so the class itself.
// In Javascript it's just regularly called constructor but you could also call 
// it SchedulerClass
interface SchedulerConstructor { 
  cron: string; // A member of the uninstantiated class/constructor is static.
  new (...args: any[]): any;
}

// Decorators get the class itself passed not an instantiation of it. This means interfaces
// we set here define the structure of the class and not of the object. This gives us
// the opportunity to use our constructor-interface to restrict which classes can be
// decorated and thus enforcing the static member cron.
export function ScheduledTaskProcessor(constructor: SchedulerConstructor) {
    // decorator logic
}

@ScheduledTaskProcessor // No compiler warning because the static is set.
class ScoringProcess {
    static cron = "test"
}

@ScheduledTaskProcessor // Error static cron not declared.
class ScoringProcessError {
}

Playground