简体   繁体   English

替代使用枚举指定 TypeScript 中的类型?

[英]Alternative to using enums for specifying types in TypeScript?

In my application I am developing an Entity-Component-System and I need a way of getting objects by their type from a Map.在我的应用程序中,我正在开发一个实体组件系统,我需要一种从 Map 中按类型获取对象的方法。 Currently I am doing this:目前我正在这样做:

class Entity {
  components: Map<CT, Component>;

  constructor() {
    this.components = new Map();
  }

  get(componentType: CT): any {
    return this.components.get(componentType);
  }
}

const enum CT {
  Null,
  Health,
  Position,
  // etc..
}

class Component {
  type: CT;

  constructor(type: CT) {
    this.type = type;
  }
}

class HealthComponent extends Component {
  amount: number;
  
  constructor() {
    super(CT.Health);

    this.amount = 0;
  }
}

And then here is some example client code:然后这里是一些示例客户端代码:

let healthComponent = new HealthComponent();
healthComponent.amount = 100;

let entity = new Entity();
entity.components.set(healthComponent.type, healthComponent);

// Later, elsewhere..
let health = entity.get(CT.Health);
console.log(health.amount);

This all works, but it's a bit cumbersome.这一切都有效,但它有点麻烦。 Every new component I make requires me to make a new entry in the CT enum, and for me to make sure it matches in the new type's constructor.我制作的每个新组件都要求我在CT枚举中创建一个新条目,并确保它在新类型的构造函数中匹配。 Ideally I'd like to be able to just do something like:理想情况下,我希望能够执行以下操作:

let healthComponent = new HealthComponent();
healthComponent.amount = 100;

let entity = new Entity();
entity.components.set(HealthComponent, healthComponent);

// Later, elsewhere..
let health = entity.get(HealthComponent);
console.log(health.amount);

But I'm not sure if that is possible.但我不确定这是否可能。 Can this be done?这可以做到吗?

I would just use string as a key and do something like:我只会使用字符串作为键并执行以下操作:

class Entity {
  components: Map<string, Component>;

  constructor() {
    this.components = new Map();
  }

  get(componentType: string): any {
    return this.components.get(componentType);
  }
}

And then use the name property of the class like that:然后像这样使用 class 的name属性:

let health = entity.get(Health.name);
console.log(health.amount);

You will have to set target in your tconfig to es6 or esnext file to make it work though.您必须在tconfig中将target设置为es6esnext文件才能使其正常工作。 This won't work for interfaces so if you are planning to use them it is also not a good approach.这不适用于接口,因此如果您打算使用它们,这也不是一个好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM