> ## 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 ECMAScript Private Field

ECMAScript private fields are a native JavaScript feature, fully supported in TypeScript, that provides strict, parse-time and runtime-enforced encapsulation for class members. By prefixing a class property, method, or accessor identifier with a hash symbol (`#`), the member becomes completely inaccessible outside the lexical scope of its containing class body.

```typescript theme={"dark"}
class Container {
    // Declaration of an ECMAScript private field
    #internalState: number;

    constructor(initialState: number) {
        this.#internalState = initialState;
    }

    // Declaration of an ECMAScript private method
    #compute(): number {
        return this.#internalState * 2;
    }

    public getResult(): number {
        return this.#compute();
    }
}
```

## Technical Characteristics

**Strict Enforcement**
Unlike TypeScript's `private` modifier, which is a compile-time only construct erased during JavaScript emission, ECMAScript private fields (`#`) guarantee hard privacy. Attempting to access a `#` field outside its class results in a `SyntaxError` in JavaScript. Because this is a parse-time error, it prevents the script from executing entirely. Furthermore, the field cannot be inspected using standard property enumeration (e.g., `Object.keys()`) or reflection.

**No Dynamic Access**
Private fields cannot be accessed dynamically using bracket notation. The identifier must be statically known and accessed via dot notation within the lexical scope of the class. Attempting to use bracket notation with a string literal does not interact with the private field at all; it merely attempts to access a standard public property whose string key happens to include a hash.

```typescript theme={"dark"}
const instance = new Container(10);

// TypeScript Compile-time Error: Property '#internalState' is not accessible outside class 'Container'.
// JavaScript Parse-time Error: SyntaxError: Private field '#internalState' must be declared in an enclosing class.
instance.#internalState; 

// TypeScript Compile-time Error: Property '#internalState' does not exist on type 'Container'.
// JavaScript Runtime: Valid syntax, but evaluates to `undefined`. It attempts to access a public property with the string key "#internalState", bypassing the private field entirely.
instance['#internalState']; 
```

**Inheritance and Shadowing**
ECMAScript private fields are strictly bound to the class that declares them. They are invisible to subclasses. If a subclass declares a private field with the exact same name as a parent class, it creates a distinct, unique slot in memory rather than overriding or shadowing the parent's field.

```typescript theme={"dark"}
class Base {
    #id = "base_id";
    
    printBaseId() {
        console.log(this.#id);
    }
}

class Derived extends Base {
    // This is a completely separate field from Base's #id
    #id = "derived_id"; 
    
    printDerivedId() {
        console.log(this.#id);
    }
}
```

## Compilation and Target Environments

TypeScript's handling of ECMAScript private fields depends on the `target` specified in the `tsconfig.json`:

* **`ES2022` or higher:** TypeScript emits the native `#` syntax directly into the compiled JavaScript.
* **`ES2015` to `ES2021`:** TypeScript downlevels the private fields using `WeakMap` instances to simulate strict runtime privacy without leaking memory.
* **Below `ES2015` (e.g., `ES5`):** ECMAScript private fields are not supported, and compilation will fail, as `WeakMap` is required for polyfilling the behavior.

<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>
