You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reacted by Boris Aranovič, Denis Zhbankov, Xiaoyun Yang, Dave, Wall, Claudiu Ceia , Eric Kirkham, Henry Sequeda González, Dima Ivanyuk, 流浪大法师 and 2 more
Reacted by abhilashvadnala, Aaron Urkin, Vahid Najafi, Brian Andress, Mubaraq Wahab, 流浪大法师, Peter Flynn, Jimmy Pruitt, Nonoroazoro, Albertinin Mourato Santos and 14 more
Reacted by Dennis, Jonathan MASSUCHETTI, Dave, Jack Hamby, Wall, Roman Makarov, Subhendu Sethi, Antoine Souesme, 流浪大法师, aviyadeveloper and 1 more
Downside is you can't use Events.Pause; you have to use AdvEvents.Pause. If you're using const enums, this is probably ok. Otherwise, it might not be sufficient for your use case.
Reacted by Anton Zhaparov, Dennis, Bradley Baysinger, Fernando Macias Pereznieto, Cody Dalton, kibar, Boris Aranovič, Amit Beckenstein, Martin Jakubík, Evilart86 and 36 more
Reacted by Artem Kamysh, Denis, Alejandro, Volodymyr, bertdk, Danny Beyrer, Bob Walker, Bogdan Vovchuk, Martin Haupt, Mykola Veryha and 2 more
Reacted by Dennis, Antoine Zazzera, Cody Dalton, Sushruth Sastry, Martin Jakubík, Dave, Krzysztof Piasecki, Nathan Alcantara, gtkatakura and 流浪大法师
Reacted by Nathan Alcantara, Feodor Rusanov and 流浪大法师
Reacted by Alexander Taratin, guptaamol, Pedro Casaubon, cyrilluce, Amit Beckenstein, Denis Zhbankov, Kaien Liao, Nathan Farkash, eduardo aleixo, Louis Christopher and 19 more
Reacted by Spencer Miller and AA
Reacted by Lorenzo Pieri and Tristan
Reacted by Alexander Taratin, guptaamol, Pedro Casaubon, Tony Samperi, Amit Beckenstein, Denis Zhbankov, ugeng, lzfee0227, 流浪大法师, Ricky and 5 more
All workarounds are nice but I would like to see the enum inheritance support from typescript itself so that I can use exhaustive checks as simple as possible.
Reacted by Ivan Shaban, Nerlin~, Alexey Pelykh, Sascha, Josh, Stefan Eilemann, Luca Borrione, waiting, Ivan Voznyakovsky, D[oa]vid Weisz and 242 more
Reacted by Alden Daniels, Noel Llevares, Vicky Leong, Viktor Zozuliak, Brian Bugh, zpbc007, Dannii Willis, Frédéric Mascaro, Loh Tong Hong, Andrei Zhidkov and 204 more
Reacted by Dani de la Cruz, Andrii Ivaniv, Jimmy Cao, Ilias, Maciej Młynarczuk, Amit Beckenstein, Andrei F, Michael Seifarth, Alejandro Celaya, luanvieirazup and 30 more
Why isn't this a feature already? No breaking changes, intuitive behavior, 80+ people who actively searched for and demand this feature – it seems like a no-brainer.
Even re-exporting enum from a different file in a namespace is really weird without extending enums (and it's impossible to re-export the enum in a way it's still enum and not object and type):
import{Fooas_Foo}from'./Foo';namespaceBar{enumFooextends_Foo{}// nope, doesn't workconstFoo=_Foo;typeFoo=_Foo;}Bar.Foo// actually not an enum
Reacted by Duma, Sergey Linnik, bySabi Files, Luke Petruzzi, danielgig, altheaschutte, Ben Sawyer, Scarlett Hobbs, prudnikovdbison, Andrei F and 14 more
I skimmed through this issue to see if anyone has posed the following question. (Seems not.)
From OP:
enumBasicEvents{Start="Start",Finish="Finish"};// extend enum using "extends" keywordenumAdvEventsextendsBasicEvents{Pause="Pause",Resume="Resume"};
Would people expect AdvEvents to be assignable to BasicEvents? (As is, for example, the case with extends for classes.)
If yes, then how well does that mesh with the fact that enum types are meant to be final and not possible to extend?
Reacted by Mark Smith, Jeka-Endorphin, Majid Jafari, Alex, Jérémy VIGNELLES, Andriy Nahornyi , Bob Walker, Disorder AA, Jan Molnár, Mykola Veryha and 1 more
Reacted by vtereshyn, Wenhan Do, Gonzalo Gallego López and Özkan Yalcinkaya
Carl Mäsak (@masak) great point. The feature people want here is definitely not like normal extends. BasicEvents should be assignable to AdvEvents, not the other way around. Normal extends refines another type to be more specific, and in this case we want to broaden the other type to add more values, so any custom syntax for this should probably not use the extends keyword, or at least not use the syntax enum A extends B {.
So here's the most likely answer at this point - we're probably not going to touch enums for a bit as there's discussion of introducing them to JS; that said, discussion here can help drive the design direction of JS.
mixing up sexual orientation with gender. Pansexuality is a sexual orientation.
limiting gender and sexual orientation options. Those are not clear cut and are based on the individual's experiences.
Also, consider if those pieces of data are needed. Most often they're not. If they are, have at least an "Other" option, although an open field would be better.
Reacted by Morgan MacKechnie, Willow Hayward, Nazario A. Ayala, GwendalBroudin-Emoko, Ryan Cavanaugh and Edie Lemoine
Reacted by Sergey, Lucas Reis, GoodbyeNJN, James Gardner, sunbeyond, Colin Burke, Ivan Palatov, Aaron Finocchiaro, Luke Digby, Vasilis Tsirimokos and 5 more
While Patrícia Villela (@patriciavillela)'s comment might seem like a detour from the main topic, I see a way to connect it to (what I see as) the main important property to preserve in all of this:
The original enum must not be affected by the extension.
We like enums because of their "closed-world" property — that's the one that gives us totality/coverage checking in switch statements, for example. If the implementation of this issue affects that guarantee, we've all lost something valuable.
From a social perspective, there's simply no way to get the original enum author's blessing — the enum is and remains closed. Patrícia Villela (@patriciavillela) was not the original author of the Gender enum, but it's possible to imagine the original author similarly objecting to their enum being extended.
From this point of view, the term "extending" (in the issue topic) is a misnomer; enums simply do not extend. "Inheriting" is half-wrong, half-OK, I guess — you get the original enum's values, but you do not in any sense participate in the original enum's type.
If spread really means the same as copying down the spreaded enum's members, then there will be a big surprise when people try to use the extending enum's value as if it were the extended enum's value and it doesn't work.
I think the big surprise here is relative to expectations set up by terms like "extending". Since we can't actually deliver on that promise without breaking a fundamental guarantee of enums (that of being closed), I'm fine with Option 1, and I think it can be made much less surprising by avoiding terms like "extending".
Regarding this:
So here's the most likely answer at this point - we're probably not going to touch enums for a bit as there's discussion of introducing them to JS; that said, discussion here can help drive the design direction of JS.
I guess what I should really be doing is head over to the tc39 repository and defend JavaScript enums against the extends keyword. 😄 This seems to be the issue for doing that.
Patrícia Villela (@patriciavillela) I meant no offense. I should not have called it sexual orientation and removed male/female. I was trying to create an example that was relatable -- I did it quickly and sloppy. I think I might have had it on my mind for news reasons. I am willing to update the original content in order to make it more correct.
Per discussion at #51310, we're officially putting this one in "Waiting for TC39" status. There's a proposal that's actively being developed which would potentially bring some sort of enum declaration form to JavaScript, and we'd like this to either proceed, or have the committee informally agree to indefinitely hold off on adding enum to JS in any form.
which will give you a type/value combination that's effectively indistinguishable from a hypothetical enum XY { ...X, three = "c", four = "d" } declaration
Reacted by Qwerty (Vítězslav Ackermann Ferko), Amit Beckenstein, Carl Mäsak, Ben Meyrick, Alejandro Pedro Recalde, Tim Kevin Oxley, Eoghan, Ayush Chothe and Soroush Falahati
Reacted by GuyDev1, Jihoo Kim and Eduardo Pellenz
Reacted by Qwerty (Vítězslav Ackermann Ferko), Amit Beckenstein, SlurpTheo, Jihoo Kim, Tristan and Itamar Cohen
I would say this is not a "good" alternative, as much as it is just that, an alternative. It's messy, sloppy and extremely hard if not impossible to remember, unless you're a pure TypeScript pro.
I don't get why:
enum B extends A {}
is not viable. It's simple, elegant, and consistent with the rest of the TypeScript syntax.
is not viable. It's simple, elegant, and consistent with the rest of the TypeScript syntax.
Alex (@whatwhywhenandwho) Well... (and sorry for repeating myself; this is well-covered in the comments above, but I realize there's a lot of them, so maybe repeating the message here might be beneficial)
...using extends as a keyword for enums sets exactly the wrong expectations, which then cannot be upheld with enums. The enum feature implies "these are the enum values, and nothing else" (closed world). The extends keyword implies "we use something as a base, and then add some more stuff" (open world). The exhaustiveness check of switch is also based on the closed-world assumption. Allowing any kind of extends semantics breaks that assumption. (Now consider using extends on an enum, but in a third-party module you neither control or even know about.)
Seeing as how the main reason for having enums is to enforce the closed-world assumption and to allow for the exhaustiveness check in switch, I am vehemently, categorically opposed to using extends in the way you propose.
Reacted by Soroush Falahati
Reacted by jhagerman-bc, Ivan Kleshnin and Luis Finke
...using extends as a keyword for enums sets exactly the wrong expectations, which then cannot be upheld with enums. The enum feature implies "these are the enum values, and nothing else" (closed world). The extends keyword implies "we use something as a base, and then add some more stuff" (open world). The exhaustiveness check of switch is also based on the closed-world assumption. Allowing any kind of extends semantics breaks that assumption. (Now consider using extends on an enum, but in a third-party module you neither control or even know about.)
Thinking about it a little bit philosophically, inheritance between classes is already a pretty weird feature. 😄 It lets you create instances of your own class which are also instances or someone else's class! Like, what's up with that? 😮
But it's something we expect from classes, and sometimes even use in healthy, well-defined ways. (Like extending base classes provided by a framework.) It works.
With enums, it runs up against the closed-world expectation, which is why enums never allow you to (a) create new instances/values of the enum besides those originally specified, nor (b) create any kind of derived enum/sub-enum with its own new instances.
Reacted by jhagerman-bc, Spencer Miller and Luis Finke
Hey guys, it's been a long time since there has been no activity here. I don't want to stir up a hornet's nest, but the problem is still relevant. Are there any plans to solve it?
shArky (@XIshArkIX) You can read Ryan Cavanaugh's response above; the tl;dr is that there's now a tc39 proposal for enums in JavaScript/EcmaScript, and it's unlikely that anything will happen with TypeScript's enum feature before that proposal lands. I think that's very reasonable; in a way, TypeScript's original enum feature already somewhat exceeded TypeScript's mission, which includes erasing types and compiling down to JavaScript, but not adding/altering runtime behavior.
I should add that the tc39 proposal is still at Stage 1 ("Under consideration") as of this writing. At a guess, it will not be accepted into the EcmaScript specification anytime soon.
...which (a) works today, (b) should satisfy those who want the behavior or "extending" an enum, but (c) doesn't suffer from the problems an extend keyword would have (discussed at length above).
Activity
nomaed commentedon Aug 3, 2017
Just played with it a little bit and it is currently possible to do this extension using an object for the extended type, so this should work fine:
aluanhaddad commentedon Aug 7, 2017
Note, you can get close with
aj-r commentedon Sep 22, 2017
Another option, depending on your needs, is to use a union type:
Downside is you can't use
Events.Pause; you have to useAdvEvents.Pause. If you're using const enums, this is probably ok. Otherwise, it might not be sufficient for your use case.serhiipalash commentedon Mar 25, 2018
We need this feature for strongly typed Redux reducers. Please add it in TypeScript.
aj-r commentedon Mar 25, 2018
Another workaround is to not use enums, but use something that looks like an enum:
Xenya0815 commentedon May 8, 2018
All workarounds are nice but I would like to see the enum inheritance support from typescript itself so that I can use exhaustive checks as simple as possible.
nOstap commentedon Sep 4, 2018
Just use class instead of enum.
guptaamol commentedon Oct 19, 2018
I was just trying this out.
There has got to be a better way of doing this.
cshaa commentedon Nov 29, 2018
Why isn't this a feature already? No breaking changes, intuitive behavior, 80+ people who actively searched for and demand this feature – it seems like a no-brainer.
Even re-exporting enum from a different file in a namespace is really weird without extending enums (and it's impossible to re-export the enum in a way it's still enum and not object and type):
LukePetruzzi commentedon Dec 18, 2018
+1
Currently using a workaround, but this should be a native enum feature.
masak commentedon Dec 21, 2018
I skimmed through this issue to see if anyone has posed the following question. (Seems not.)
From OP:
Would people expect
AdvEventsto be assignable toBasicEvents? (As is, for example, the case withextendsfor classes.)If yes, then how well does that mesh with the fact that enum types are meant to be final and not possible to extend?
alangpierce commentedon Dec 21, 2018
Carl Mäsak (@masak) great point. The feature people want here is definitely not like normal
extends.BasicEventsshould be assignable toAdvEvents, not the other way around. Normalextendsrefines another type to be more specific, and in this case we want to broaden the other type to add more values, so any custom syntax for this should probably not use theextendskeyword, or at least not use the syntaxenum A extends B {.masak commentedon Dec 21, 2018
On that note, I did like the suggestion of spread for this from OP.
Because spreading already carries the expectation of the original being shallow-cloned into an unconnected copy.
65 remaining items
freakzlike commentedon Feb 17, 2022
Nazario A. Ayala (@nazarioa)
You can inherit the type from the object, so you don't need to define the values twice.
whut commentedon Feb 22, 2022
Daniel Rosenwasser (@DanielRosenwasser) Ugh, looks like I missed your comment.
For the reference this is probably where the mentioned discussion happens: https://github.com/Jack-Works/proposal-enum
patriciaverso commentedon Apr 11, 2022
Please, Nazario A. Ayala (@nazarioa) and freakzlike, refrain from two things:
Also, consider if those pieces of data are needed. Most often they're not. If they are, have at least an "Other" option, although an open field would be better.
masak commentedon Apr 12, 2022
While Patrícia Villela (@patriciavillela)'s comment might seem like a detour from the main topic, I see a way to connect it to (what I see as) the main important property to preserve in all of this:
The original enum must not be affected by the extension.
We like enums because of their "closed-world" property — that's the one that gives us totality/coverage checking in
switchstatements, for example. If the implementation of this issue affects that guarantee, we've all lost something valuable.From a social perspective, there's simply no way to get the original enum author's blessing — the enum is and remains closed. Patrícia Villela (@patriciavillela) was not the original author of the
Genderenum, but it's possible to imagine the original author similarly objecting to their enum being extended.From this point of view, the term "extending" (in the issue topic) is a misnomer; enums simply do not extend. "Inheriting" is half-wrong, half-OK, I guess — you get the original enum's values, but you do not in any sense participate in the original enum's type.
Ryan Cavanaugh (@RyanCavanaugh) wrote:
I think the big surprise here is relative to expectations set up by terms like "extending". Since we can't actually deliver on that promise without breaking a fundamental guarantee of enums (that of being closed), I'm fine with Option 1, and I think it can be made much less surprising by avoiding terms like "extending".
Regarding this:
I guess what I should really be doing is head over to the tc39 repository and defend JavaScript enums against the
extendskeyword. 😄 This seems to be the issue for doing that.nazarioa commentedon Apr 21, 2022
Patrícia Villela (@patriciavillela) I meant no offense. I should not have called it sexual orientation and removed male/female. I was trying to create an example that was relatable -- I did it quickly and sloppy. I think I might have had it on my mind for news reasons. I am willing to update the original content in order to make it more correct.
RyanCavanaugh commentedon Oct 27, 2022
Per discussion at #51310, we're officially putting this one in "Waiting for TC39" status. There's a proposal that's actively being developed which would potentially bring some sort of
enumdeclaration form to JavaScript, and we'd like this to either proceed, or have the committee informally agree to indefinitely hold off on addingenumto JS in any form.A good alternative is:
which will give you a type/value combination that's effectively indistinguishable from a hypothetical
enum XY { ...X, three = "c", four = "d" }declarationwhatwhywhenandwho commentedon Dec 16, 2022
I would say this is not a "good" alternative, as much as it is just that, an alternative. It's messy, sloppy and extremely hard if not impossible to remember, unless you're a pure TypeScript pro.
I don't get why:
is not viable. It's simple, elegant, and consistent with the rest of the TypeScript syntax.
masak commentedon Dec 19, 2022
Alex (@whatwhywhenandwho) Well... (and sorry for repeating myself; this is well-covered in the comments above, but I realize there's a lot of them, so maybe repeating the message here might be beneficial)
...using
extendsas a keyword for enums sets exactly the wrong expectations, which then cannot be upheld with enums. The enum feature implies "these are the enum values, and nothing else" (closed world). Theextendskeyword implies "we use something as a base, and then add some more stuff" (open world). The exhaustiveness check ofswitchis also based on the closed-world assumption. Allowing any kind ofextendssemantics breaks that assumption. (Now consider usingextendson an enum, but in a third-party module you neither control or even know about.)Seeing as how the main reason for having enums is to enforce the closed-world assumption and to allow for the exhaustiveness check in
switch, I am vehemently, categorically opposed to usingextendsin the way you propose.alita-moore commentedon Jun 24, 2023
what about
enum B includes A { }? either way, are there plans to implement this functionality?masak commentedon Jun 25, 2023
Thinking about it a little bit philosophically, inheritance between classes is already a pretty weird feature. 😄 It lets you create instances of your own class which are also instances or someone else's class! Like, what's up with that? 😮
But it's something we expect from classes, and sometimes even use in healthy, well-defined ways. (Like extending base classes provided by a framework.) It works.
With enums, it runs up against the closed-world expectation, which is why enums never allow you to (a) create new instances/values of the enum besides those originally specified, nor (b) create any kind of derived enum/sub-enum with its own new instances.
🔨 (grapher) replace some enum types / TAS-709 (#4170)
XIshArkIX commentedon May 25, 2026
Hey guys, it's been a long time since there has been no activity here. I don't want to stir up a hornet's nest, but the problem is still relevant. Are there any plans to solve it?
masak commentedon May 25, 2026
shArky (@XIshArkIX) You can read Ryan Cavanaugh's response above; the tl;dr is that there's now a tc39 proposal for enums in JavaScript/EcmaScript, and it's unlikely that anything will happen with TypeScript's enum feature before that proposal lands. I think that's very reasonable; in a way, TypeScript's original enum feature already somewhat exceeded TypeScript's mission, which includes erasing types and compiling down to JavaScript, but not adding/altering runtime behavior.
I should add that the tc39 proposal is still at Stage 1 ("Under consideration") as of this writing. At a guess, it will not be accepted into the EcmaScript specification anytime soon.
Meanwhile, I recommend Ryan's workaround:
...which (a) works today, (b) should satisfy those who want the behavior or "extending" an enum, but (c) doesn't suffer from the problems an
extendkeyword would have (discussed at length above).