private keyword and private fields

https://stackoverflow.com/questions/59641564/what-are-the-differences-between-the-private-keyword-and-private-fields-in-types

private key (typescript关键字)属于编译时注解。

private fields (ES 私有字段) 属于运行时检查。

The private keyword in TypeScript is a compile time annotation. It tells the compiler that a property should only be accessible inside that class:

class PrivateKeywordClass {
    private value = 1;
}

const obj = new PrivateKeywordClass();
obj.value // compiler error: Property 'value' is private and only accessible within class 'PrivateKeywordClass'.

However compile time checking can be easily bypassed, for example by casting away the type information:

const obj = new PrivateKeywordClass();
(obj as any).value // no compile error

The privatekeyword is also not enforced at runtime

Private keyword

The private keyword in TypeScript is a compile time annotation. It tells the compiler that a property should only be accessible inside that class:

class PrivateKeywordClass {
    private value = 1;
}

const obj = new PrivateKeywordClass();
obj.value // compiler error: Property 'value' is private and only accessible within class 'PrivateKeywordClass'.

However compile time checking can be easily bypassed, for example by casting away the type information:

const obj = new PrivateKeywordClass();
(obj as any).value // no compile error

The privatekeyword is also not enforced at runtime

Emitted JavaScript

When compiling TypeScript to JavaScript, the private keyword is simply removed:

class PrivateKeywordClass {
    private value = 1;
}

Becomes:

class PrivateKeywordClass {
    constructor() {
        this.value = 1;
    }
}

From this, you can see why the private keyword does not offer any runtime protection: in the generated JavaScript it's just a normal JavaScript property.

Private fields

Private fields ensure that properties are kept private at runtime:

class PrivateFieldClass {
    #value = 1;

    getValue() { return this.#value; }
}

const obj = new PrivateFieldClass();

// You can't access '#value' outside of class like this
obj.value === undefined // This is not the field you are looking for.
obj.getValue() === 1 // But the class itself can access the private field!

// Meanwhile, using a private field outside a class is a runtime syntax error:
obj.#value

// While trying to access the private fields of another class is 
// a runtime type error:
class Other {
    #value;

    getValue(obj) {
        return obj.#value // TypeError: Read of private field #value from an object which did not contain the field
    }
}

new Other().getValue(new PrivateKeywordClass());