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
