Currently, You can't extend enum in TypeScript

Another option is to use type:

enum Color1 {
    Red = "Red",
    Green = "Green"
}

enum Color2 {
    Yellow = "Yellow",
    Blue = "Blue"
}

define a new type named Colors :

type Colors = Color1 | Color2;

Then you can use it as below :

class AppComponent {
    public color: Colors;
    
    ngOnInit(): void {
      const Colors = { ...Color2, ...Color1 };
      this.color = Colors.Red; // Colors.Green or Colors.Yellow or Colors.Blue
    }
}

Stackblitz Here (Angular)

Stackblitz Here (Typescript)

Answer from Abolfazl Roshanzamir on Stack Overflow
Top answer
1 of 4
109

Currently, You can't extend enum in TypeScript

Another option is to use type:

enum Color1 {
    Red = "Red",
    Green = "Green"
}

enum Color2 {
    Yellow = "Yellow",
    Blue = "Blue"
}

define a new type named Colors :

type Colors = Color1 | Color2;

Then you can use it as below :

class AppComponent {
    public color: Colors;
    
    ngOnInit(): void {
      const Colors = { ...Color2, ...Color1 };
      this.color = Colors.Red; // Colors.Green or Colors.Yellow or Colors.Blue
    }
}

Stackblitz Here (Angular)

Stackblitz Here (Typescript)

2 of 4
53

I've just stumbled across this post from 2018 that explains how to do it with string based enums (see the original comment).

The key seems to be to declare a type AND a const with the same name.

Here's an annotated / fruity version:

enum someEnum {
  Apple = 'Apple',
  Banana = 'Banana'
}

enum extendedEnum {
  Pear = 'Pear',
  Grape = 'Grape'
}

// The key seems to be to declare a type AND
// a const with the same name

type AllFruits = someEnum | extendedEnum;
const AllFruits = {...someEnum, ...extendedEnum};

let f: AllFruits = AllFruits.Grape;

The original poster (who, by all rights, seems to have been a contributor to TypeScript and knows what they're talking about) mentions that, using this method, you can't use something like AllFruits.Grape as a 'type literal', which means you can't do this:

// This error will appear: 
// 'AllFruits' only refers to a type, but is being used as a namespace here.

interface FruitBowl {
    fruit: AllFruits.Grape    
}

but this can be fixed with (something quite ugly) like:

interface FruitBowl {
    fruit: typeof AllFruits.Grape    
}

I guess this is one of the 'type workarounds' that others have mentioned.

(All credit to https://github.com/alangpierce)

🌐
LogRocket
blog.logrocket.com › home › how to extend enums in typescript
How to extend enums in TypeScript - LogRocket Blog
August 29, 2024 - Learn how to extend enums in TypeScript using techniques like unions types, spread syntax, and const assertions.
Discussions

Extending enum
Suggestion Extending enums 🔍 Search Terms extend enum enum extending enum ✅ Viability Checklist My suggestion meets these guidelines: This wouldn't be a breaking change in existing TypeScript/J... More on github.com
🌐 github.com
1
July 23, 2023
Is there a mechanism for extending enums?

You can't inherit from enums in TypeScript, but could using unions help?

enum State 
{
    State1,
    State2
}

enum AnotherState
{
     State1,
     State2,
     State3,
     State4
}

const x: State | AnotherState = State.State1;

const y: State | AnotherState = AnotherState.State3;
More on reddit.com
🌐 r/typescript
5
11
November 25, 2017
Extending string-based enums
Before string based enums, many would fall back to objects. Using objects also allows extending of types. For example: const BasicEvents = { Start: "Start", Finish: "Finish" }; ... More on github.com
🌐 github.com
86
August 3, 2017
Allow "T extends enum" generic constraint
TypeScript has a discrete enum type that allows various compile-time checks and constraints to be enforced when using such types. It would be extremely useful to allow generic constraints to be limited to enum types - currently the only way to do this is via T extends string | number which ... More on github.com
🌐 github.com
39
March 27, 2019
🌐
TypeScript
typescriptlang.org › docs › handbook › enums.html
TypeScript: Handbook - Enums
The biggest argument in favour of this format over TypeScript’s enum is that it keeps your codebase aligned with the state of JavaScript, and when/if enums are added to JavaScript then you can move to the additional syntax.
🌐
GitHub
github.com › microsoft › TypeScript › issues › 55114
Extending enum · Issue #55114 · microsoft/TypeScript
July 23, 2023 - Maybe even include the Omit operator so we could technically omit a value when extending an enum.
Author   Vincent-Lavallee
🌐
DEV Community
dev.to › egorovsa › how-to-extend-enum-in-typescript-cj4
How to extend enum in TypeScript - DEV Community
September 15, 2022 - // describe an enum object const MySuperEnum = { ONE: 'ONE', TWO: 'TWO' } as const // create the MySuperEnum type type MySuperEnum = typeof MySuperEnum[keyof typeof MySuperEnum]; What is as const? Please click to find out more. Cool! Now our MySuperEnum is defined in a different way! It is time to create new MyMoreSuperEnum that will be extended with MySuperEnum.
🌐
Medium
medium.com › @awwwesssooooome › interviewer-how-to-implement-inheritance-with-enums-in-typescript-67283bf5ee4e
Interviewer: How to implement inheritance with enums in TypeScript? | by Awwwesssooooome | Medium
February 20, 2024 - Although TypeScript enums do not support direct inheritance, you can indirectly “inherit” enum values by creating a new enum and then merging it with another enum into a union type. enum BaseEnum { A = 'A', B = 'B', } enum ExtendedEnum { ...
Find elsewhere
🌐
Mimo
mimo.org › glossary › typescript › enum
TypeScript Enum: Syntax, Usage, and Examples
Master TypeScript enums to define constants, improve readability, and ensure consistency. Use string enums for debugging and union types for lighter code.
🌐
Reddit
reddit.com › r/typescript › [deleted by user]
[deleted by user] : r/typescript
November 25, 2017 - enum State { State1, State2 } enum AnotherState { State1, State2, State3, State4 } const x: State | AnotherState = State.State1; const y: State | AnotherState = AnotherState.State3;
🌐
DEV Community
dev.to › logrocket › how-to-extend-enums-in-typescript-2llb
How to extend enums in TypeScript - DEV Community
July 6, 2022 - The short answer is no, you can’t extend enums because TypeScript offers no language feature to extend them.
🌐
Refine
refine.dev › home › blog › tutorials › a detailed guide on typescript enum with examples
A Detailed Guide on TypeScript Enum with Examples | Refine
January 6, 2025 - Towards the end, we explored the types generated by the enums and leveraged them to derive our own subtypes. Finally we implemented a basic PersonalSubscription class that demonstrates the convenience offered by objects and types generated by TypeScript enums.
🌐
Zod
zod.dev › api
Defining schemas | Zod
It's more tsc-efficient — the .extend() method can be expensive on large schemas, and due to a TypeScript limitation it gets quadratically more expensive when calls are chained
🌐
GitHub
github.com › microsoft › TypeScript › issues › 17592
Extending string-based enums · Issue #17592 · microsoft/TypeScript
August 3, 2017 - enum BasicEvents { Start = "Start", Finish = "Finish" }; // extend enum using "extends" keyword enum AdvEvents extends BasicEvents { Pause = "Pause", Resume = "Resume" };
Author   nomaed
🌐
GitHub
github.com › microsoft › TypeScript › issues › 30611
Allow "T extends enum" generic constraint · Issue #30611 · microsoft/TypeScript
March 27, 2019 - export enum StandardSortOrder { Default, Most, Least } export enum AlternativeSortOrder { Default, High, Medium, Low } export interface IThingThatUsesASortOrder<T extends enum> { // doesn't compile sortOrder: T; } ... Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript
Author   IanKemp
🌐
Hacker News
news.ycombinator.com › item
TypeScript enums: use cases and alternatives | Hacker News
January 22, 2025 - Enums made some sense back when TS didn't have any of these. They don't really make a lot of sense now. I think they're effectively deprecated, to the point that I wonder why they don't document them as deprecated · I agree they should just formally deprecate it
Top answer
1 of 1
7

This is a longstanding issue with numeric enums. For whatever reason (some backwards compatibility they can't break), a number is seen as assignable to a numeric enum, so you can do this with no error:

enum E {
  V = 100
}
const num = 100;
const e: E = num; // no error 

What's more, numeric enums are also intended to act as bit fields, and therefore they intentionally don't require that a value of an numeric enum type is one of the specific declared values:

enum Color {
  RED = 1,
  GREEN = 2,
  BLUE = 4
}
const red: Color = Color.RED; // 1
const yellow: Color = Color.RED | Color.GREEN; // 3 
const white: Color = Color.RED | Color.GREEN | Color.BLUE; // 7 
const octarine: Color = Math.pow(Color.BLUE - Color.RED, Color.GREEN); // 9 

Yeah, I don't know why you can do any math you'd like with a numeric enum, but you can. The upshot is, essentially any number is assignable to any numeric enum, and vice versa.


If you want to prevent this you might want to give up on actual enums and instead make your own types and values with behavior you control. It's more verbose but it might meet your needs:

const MyList = {
  A: 0,
  B: 1
} as const;
type MyList = typeof MyList[keyof typeof MyList]

const MyList2 = {
  C: 0
} as const;
type MyList2 = typeof MyList2[keyof typeof MyList2]

Those behave similarly to your old enums (although there are some missing types) but they will be much more strict about behavior:

function test<T>(input: MyList | T): void {}

test(0); // okay
test(1); // okay
test(2); // okay, 2 is inferred as T
test<MyList2>(123); // error! 123 is not assignable to 0 | 1

Link to code

🌐
TypeScript
typescriptlang.org › docs › handbook › 2 › generics.html
TypeScript: Documentation - Generics
To do so, we’ll create an interface that describes our constraint. Here, we’ll create an interface that has a single .length property and then we’ll use this interface and the extends keyword to denote our constraint: