1

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)
  }

}
2
  • 1
    The error explains the problem. Either make the property only abstract or only static. Commented Mar 17, 2021 at 21:49
  • As mentioned before, why not just make your cron string static and overwrite it, when needed? Commented Mar 18, 2021 at 10:10

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

amazing! super well done Mirco S! thanks for heping ot and welcome to SO

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.