Arnaud Dev
Arnaud Dev

Reputation: 53

Type for a class as a function param

At first, Here is the core Interface :

// IMySuperInterface.interface.ts

export interface IMySuperInterface<T = any> {
  handle(arg?: any): Promise<T>;
}

Basically, I just need a common type for ==> child class with an 'handle' function. Something like :

function MyDummyFunction (param: {{class that extends IMySuperInterface)}})

I try to register all the class in my app that implement my 'IMySyperInterface'

// MySuperImplementation.service.ts
@Feature('ReferenceA')
export class MySuperImplementation
  implements IMySuperInterface {

 constructor(private readonly logger: myLoggerService) {
    this.logger.setContext(this);
  }

  async handle(someDummy: any): Promise<void> {
    ....
  }
}

And Here the definition of the Decorator

// feature.decorator.ts
const _mapping = new Map<string, anyOrIdontKnowWhatToDo>();

export function Feature(key: string) {

  return function (target: **HERE WHAT CAN I WRITE  ??????**) {
    Feature.cache.set(key, target);
    return target;
  };
}

I try to find some sort of 'AtLeastContains<IMySuperInterface>' or Type<IMySuperInterface>

with

export interface Type<T = any> extends Function {
    new (...args: any[]): T;
}

But I get :

I am lost :(.. How can I defined as a param of my function a Class that implements my Interface ? Note: The argument in the constructor of my class change all the time and also the argument of the function in the interface.

Upvotes: 0

Views: 93

Answers (1)

Jay McDoniel
Jay McDoniel

Reputation: 70412

Today I learned it is possible to type a decorator to specific classes. Anyways, I was able to implement something similar like this:

export function Command(
  options: CommandMetadata,
): <TFunction extends CommandRunner>(target: TFunction) => void | TFunction {
  return (target) => {
    Reflect.defineMetadata(CommandMeta, options, target);
    return target;
  };
}

This is a fully typed decorator, instead of using the ClassDecorator type so that I can set the target's generic type correctly. Should be roughly what you're looking for. Just replace CommandRunner with your interface and the return of the anon target function with your decorator's logic.

Upvotes: 2

Related Questions