首页 > 解决方案 > 工厂方法中的返回类型

问题描述

给定以下类层次结构,是否以及如何将具体的处理程序实例类型映射到特定的事件类实例?

class Event {}

class EventA extends Event {
  constructor(public readonly value: number) {
    super();
  }
}

class EventB extends Event {
  constructor(public readonly message: string) {
    super();
  }
}

abstract class EventHandler<T> {
  public abstract run(): T;
}

class EventAHandler extends EventHandler<number> {
  constructor(private readonly event: EventA) {
    super();
  }

  public run() {
    return this.event.value + 1;
  }
}

class EventBHandler extends EventHandler<string> {
  constructor(private readonly event: EventB) {
    super();
  }

  public run() {
    return this.event.message + ' world!';
  }
}

class EventHandlerFactory {
  static createHandler<T extends Event>(event: T) {
    if (event instanceof EventA) {
      return new EventAHandler(event);
    }

    if (event instanceof EventB) {
      return new EventBHandler(event);
    }

    throw new Error('Not implemented!');
  }
}

const event = new EventA(1);

// T in createHandler is inferred as EventA
const handler = EventHandlerFactory.createHandler(event); // EventAHandler | EventBHandler

const result = handler.run(); // string | number -> should be number

操场

我想要的是handler推断(或成为)EventAHandler而不是联合类型(没有类型断言as),因此我可以确定特定处理程序的结果类型。

标签: typescriptgenericsfactory-pattern

解决方案


您可以使用条件类型来完成这项工作,但您必须进行一些转换:

type EventHandlerFromEvent<T extends Event> =
  T extends EventA ? EventAHandler : EventBHandler;

class EventHandlerFactory {
  static createHandler<T extends Event>(event: T): EventHandlerFromEvent<T> {
    if (event instanceof EventA) {
      return new EventAHandler(event) as EventHandlerFromEvent<T>;
    }

    if (event instanceof EventB) {
      return new EventBHandler(event) as EventHandlerFromEvent<T>;
    }

    throw new Error("Not implemented!");
  }
}

推荐阅读