0

Here an example

interface ICommandHandler<T> {
  type: string // how to ensure string == T.name ?
  handle(command: T): void;
}

interface ICommand {}

class CreateTaskCommand implements ICommand{}

class CreateTaskCommandHandler implements ICommandHandler<CreateTaskCommand> {
  type = "CreateTaskCommanD" // typo
  handle(command: CreateTaskCommand) {}
}

My goal is to ensure type property equals CreateTaskCommand string in CreateTaskCommandHandler.

My previous example didn't raise a typescript error.

Guillaume Vincent
  • 13,355
  • 13
  • 76
  • 103
  • Given TS is structural typing - it would be unlikely there is any way to obtain a "name" of the type. – zerkms Dec 17 '19 at 09:20
  • I'm not sure if you can statically check that, but everything [here](https://stackoverflow.com/questions/10314338/get-name-of-object-or-class) is still relevant. – Etheryte Dec 17 '19 at 09:21
  • Is the purpose of the `type` field to conditionally execute some code based on the type of the child interface? If so, there is another way of achieving that. – tony Dec 17 '19 at 09:30
  • @tony yes exactly, I want to ensure I can't create a handler for a command that doesn't exists – Guillaume Vincent Dec 17 '19 at 09:39
  • @GuillaumeVincent Would making the type field static and referring to it by the base class work in that case? – Etheryte Dec 17 '19 at 09:55
  • @nit this is what I'm doing, it's just I'm not protecting myself or other dev with writing a typo. I will use the class in the constructor and extract the name instead of asking the developer to write it as a solution – Guillaume Vincent Dec 17 '19 at 10:10
  • @GuillaumeVincent There is no room for making a typo if you use a static member, you need to reference the class, you don't write a string constant. – Etheryte Dec 17 '19 at 12:51

1 Answers1

0

Maybe you should try to use a static property in the command.
Even if you've got a typo, it'll still works.

interface ICommandHandler<T> {
  canHandle(command:T): boolean; 
  handle(command: T): void;
}

interface ICommand {
  type: string;
}

class CreateTaskCommand implements ICommand{
  static commandName: string = 'CreateTaskCommand'
  type = CreateTaskCommand.commandName;
}

class CreateTaskCommandHandler implements ICommandHandler<CreateTaskCommand> {
  canHandle(command: CreateTaskCommand): boolean {
    return command.type === CreateTaskCommand.commandName;
  }
  handle(command: CreateTaskCommand) {}
}
MiniKeb
  • 23
  • 3