Vyhledávání na webu

Jak složím enum z jiného enumu v TypeScriptu?


Mám výčet obsahující některé libovolné hodnoty a chci automaticky namapovat hodnoty tohoto výčtu na jiný výčet 1:1 (s nějakým libovolným přídavkem). Jaký by byl nejidiomatičtější způsob, jak tohoto úkolu dosáhnout?

Chci udělat něco jako přidat Element.keys+"Magic" do výčtu Skills deklarativním způsobem a pak mít tyto hodnoty k dispozici jako klíče, aniž bych musel opakovat práci a přidávat příponu.

enum Element {
  Air,
  Fire,
  Earth,
  Water
}

-->

enum Skills {
  // Unrelated Skills
  Unarmed,
  LightArmor,
  etc. . .

  // 1-to-1 Mapping
  AirMagic,
  FireMagic,
  EarthMagic,
  WaterMagic
}

Odpověď č. 1

V podstatě se ptáte, jak složit a rozšířit enum navzájem, tedy rozšiřovat a skládat jejich vnitřní členy, při kompilaci a s jednoduchými operacemi množin.

Stručně: nemůžeš.

Jelikož jsou výčty (enums) definovány při překladu, jejich množina členů je statická a nelze ji odvozovat z jiných výčtů. Můžete mít vypočítané členy, ale to je pro hodnotu, kterou obsahují.

Abychom k enum měli přístup a manipulovali s ním, jak jste požadoval v otázce, potřebovali byste přístup k metaprogramování nad vašimi enumy, tj. použití dekorátorů na ně. Ale to v současnosti v Typescriptu není možné.

Má rada by byla použít class a/nebo type. Pro více informací se odkazujte na tuto odpověď.

Odpověď č. 2

Odpovídám na svou vlastní otázku pro případ, že by se někdo snažil dosáhnout něčeho podobného. . .


Ačkoliv se nezdá, že by bylo možné tento úkol splnit pomocí výčtů (enumů), podařilo se mi něco podobného s použitím 'šablonových literálových typů'.

type Element =
  | "Air"
  | "Fire"
  | "Earth"
  | "Water";
type Skills =
  | "Unarmed"
  | "LightArmor"
  | `${Element}Magic`;

To vede k typu sjednocení řetězců takto: "Bez zbraně" | "Lehká zbroj" | "Vzdušná magie" | "Ohnivá magie" | "Zemní magie" | "Vodní magie"


Zdroje

https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html

https://www.typescriptlang.org/play?#code/C4TwDgpgBAogNhAthAdsAKuaBeKAiAQQEsAnPKAH3wDFSJyq8YBDE4ACwfwHVngIyAbgCwAKDGhIUAMoBrInDgBnKLjwBVFK2QATLngAyRAObtgBEogD2ZSlAAGAEgDe8JKgxYAvgFlmxogBjexFxUQAzAFcUQOAiKxQofiVgAAoleUUALhlM5QBKKGcxKChAhKUrBAA6OCtjdLz8sS8xMQB6dqhMKWYoFJIiFGModgFocJsoZkjgK3LEMAQ4hOqJCBTUwlI-AMC8ZrCgA