Skip to content

Visibility

Rule

Use ES2022 private field declaration instead of using private keyword

  • True privacy - Unlike TypeScript's private modifier, which is only enforced during compilation, # private fields provide true runtime privacy. They cannot be accessed outside the class, even with JavaScript runtime tricks.
  • JavaScript standard - This is now part of the JavaScript language standard (ES2022), not just a TypeScript feature.
  • No need for transpilation - Private fields work natively in modern browsers and Node.js environments.
  • Name collision prevention - Private fields won't collide with public fields of the same name.
  • Works with plain JavaScript - Can be used in plain JavaScript files, not just TypeScript.
  • Redundant - The public attribute becomes useless and can therefore be unambiguously deleted

Examples

🚨 DON’T

class UserService {
    private readonly httpClient = inject(HttpClient);
    private readonly currentUser = signal<User | null>(null);

    public readonly isLoggedIn = computed(() => !!this.currentUser());

    public async login(credentials: LoginCredentials): Promise<void> {
        // Implementation
    }

    public logout(): void {
        this.currentUser.set(null);
    }

    private init(): void {
        // Implementation
    }
}

✅ DO

class UserService {
    readonly #httpClient = inject(HttpClient);
    readonly #currentUser = signal<User | null>(null);

    readonly isLoggedIn = computed(() => !!this.currentUser());

    async login(credentials: LoginCredentials): Promise<void> {
        // Implementation
    }

    logout(): void {
        this.currentUser.set(null);
    }

    #init(): void {
        // Implementation
    }
}