> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript Heterogeneous Enum

A heterogeneous enum in TypeScript is an enumeration that contains a mixture of both string and numeric member values. It combines the distinct compilation behaviors and type-checking rules of both numeric and string enums within a single data structure.

```typescript theme={"dark"}
enum HeterogeneousEnum {
    No = 0,
    Yes = "YES",
    Pending = 1,
    Unknown // Implicitly resolves to 2
}
```

## Initialization Rules

The TypeScript compiler enforces strict initialization rules when mixing types within an enum:

* **String Members:** Must be explicitly initialized with a string literal.
* **Numeric Members:** Can be explicitly initialized or implicitly auto-incremented.
* **Positional Dependency:** If an uninitialized member immediately follows a string member, the compiler will throw an error (`TS1061: Enum member must have initializer`). Auto-incrementing is only valid if the preceding member resolves to a numeric value.

```typescript theme={"dark"}
enum InvalidEnum {
    A = "TEXT",
    B // Error: Enum member must have initializer.
}
```

## Reverse Mapping Behavior

TypeScript handles the transpilation of string and numeric enum members differently. Numeric enums generate a **reverse mapping** (value-to-key) in the emitted JavaScript, whereas string enums only generate a **forward mapping** (key-to-value).

In a heterogeneous enum, the compiler applies these rules on a per-member basis. Only the numeric members will populate the reverse mapping object.

**TypeScript Source:**

```typescript theme={"dark"}
enum Status {
    Active = "ACTIVE",
    Code = 100
}
```

**Emitted JavaScript:**

```javascript theme={"dark"}
var Status;
(function (Status) {
    // Forward mapping only for string member
    Status["Active"] = "ACTIVE";
    
    // Forward and reverse mapping for numeric member
    Status[Status["Code"] = 100] = "Code";
})(Status || (Status = {}));
```

If you inspect the resulting `Status` object at runtime, it evaluates to:

```javascript theme={"dark"}
{
    "Active": "ACTIVE",
    "Code": 100,
    "100": "Code" // Reverse mapping exists only for the numeric member
}
```

## Type Resolution

At the type level, a heterogeneous enum creates a union type of its unique, opaque members (`Config.Path | Config.Timeout`). TypeScript treats string enum members as nominal types. This means the raw string literal `"/usr/bin"` is not assignable to `Config.Path`, and the enum's underlying type is not structurally equivalent to a standard literal union like `"/usr/bin" | 5000`.

When assigning enum members to variables, TypeScript's type inference behaves differently depending on the declaration keyword:

```typescript theme={"dark"}
enum Config {
    Path = "/usr/bin",
    Timeout = 5000
}

// Explicitly typed as the enum union: Config.Path | Config.Timeout
let explicitValue: Config = Config.Path; 

// Widens to the parent enum type: Config
let widenedValue = Config.Path;

// Inferred strictly as the specific literal member type: Config.Path
const inferredValue = Config.Path;
```

Because of the structural differences in reverse mapping and the lack of implicit type coercion between strings and numbers, bitwise operations (which are common with numeric enums) cannot be safely applied to the string members of heterogeneous enums. Attempting to apply bitwise operators to a string member results in a strict compiler error. Because TypeScript treats these members as nominal types, the error references the specific enum member's literal type rather than the primitive `string` type (e.g., `Operator '&' cannot be applied to types 'Config.Path' and 'number'`).

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor TypeScript Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
