【问题标题】:How to use an interface mapping to create a new type?如何使用接口映射来创建新类型?
【发布时间】:2021-07-08 14:42:03
【问题描述】:

在 Typescript 中可以做到这样的事情吗?

const enum ET {
  Collision,
  Dying,
  Collected
}

interface EventMap {
  [ET.Collision]: CollisionEvent;
  [ET.Dying]: DyingEvent;
  [ET.Collected]: CollectedEvent;
}

class GameEvent {
  static grabFromPool(type: ET) {
    let entry = GameEvent.pool[type];

    if (entry.length === 0) {
      return new EventMap[type](); // this line is throwing the error
    } else {
      return entry.pop();
    }
  }

  private static pool: Array<Array<GameEvent>> = [ [], [], [] ];
}

我正在尝试创建一个对象池。我标记的行出现以下错误:

'EventMap' only refers to a type, but is being used as a value here.ts(2693)

我正在尝试根据给定的类型参数 (ET) 实例化相应的类(例如:CollisionEvent)。

【问题讨论】:

  • 这不完全是minimal reproducible example,因为我不知道CollisionEvent 等是什么,但也许你正在寻找this...你不能在运行时使用接口;为什么不将接口替换为包含类构造函数的运行时对象?
  • @jcalz 像CollisionEvent 这样的东西对于这个例子基本上可以被认为是一个空类。
  • 好的,我知道我只需要删除 interface 关键字。不幸的是,我需要一个接口映射(请参阅我之前的问题了解原因:stackoverflow.com/questions/68295113/…)那么我是否只需要维护两个映射,或者有没有办法自动从另一个创建一个?
  • 你可以从你的常量生成你的类型,比如this

标签: typescript pool


【解决方案1】:

在您的代码中,EventMap 只是一个类型,没有运行时值。你需要一个真实的对象:

const EventMap = {
  [ET.Collision]: CollisionEvent,
  [ET.Dying]: DyingEvent,
  [ET.Collected]: CollectedEvent,
}

如果需要类型:

type EventMap = typeof EventMap
// Inferred as this \/
{
    0: typeof CollisionEvent;
    1: typeof DyingEvent;
    2: typeof CollectedEvent;
}

请注意,在 type 表达式中,CollisionEvent 指代类的实例,typeof CollisionEvent 指代类及其构造函数。

【讨论】:

  • 好的,很高兴知道这一点。不幸的是,我还需要一个接口映射(上面解释了为什么)。有没有办法从另一个自动构建一个,还是我只需要维护两者?
猜你喜欢
  • 2023-02-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 2021-09-16
  • 1970-01-01
  • 2022-08-04
相关资源
最近更新 更多