Powrót do: TypeScript dla Testera – Ekspresowe Podstawy (i za darmo!)
Modyfikatory dostępu w klasach
TIP: Cały kod do poszczególnych lekcji, dodatkową teorię i linki z tej i innych lekcji - znajdziesz w darmowym repozytorium - https://github.com/jaktestowac/typescript-dla-testera
Chcesz dokładniej poznać TypeScript? Sprawdź nasz Program JavaScript i TypeScript dla Testerów
Prezentacja
Tu w przyszłości mogą pojawić się dodatkowe materiały w postaci prezentacji etc.
Dodatkowe materiały
Modyfikatory dostępu określają, skąd możesz odczytać/zaktualizować pole lub wywołać metodę klasy.
W TypeScript masz: public (domyślnie), private, protected oraz kwalifikator readonly.
Dodatkowo istnieją prywatne pola ECMAScript z #nazwa (egzekwowane w runtime).
public (domyślne) i readonly
// public is default; readonly prevents reassignment after init
class Product {
readonly id: number; // can be set once
name: string; // public by default
constructor(id: number, name: string) {
this.id = id; // OK (initialization)
this.name = name;
}
}
const p = new Product(1, 'Book');
// p.id = 2; // ❌ Error: cannot assign to 'id' because it is a read-only property
p.name = 'Notebook'; // ✅ OK
private – tylko wewnątrz klasy
// 'private' members are only accessible inside the class
class Counter {
private value = 0;
increment() {
this.value++;
}
current() {
return this.value;
}
}
const c = new Counter();
c.increment();
console.log(c.current()); // 1
// console.log(c.value); // ❌ Error: 'value' is private
protected – dla klasy i klas pochodnych
// 'protected' is visible in subclasses
class User {
protected role: string = 'user';
isAdmin(): boolean {
return this.role === 'admin';
}
}
class AdminUser extends User {
promote() {
this.role = 'admin'; // ✅ allowed in subclass
}
}
const u = new AdminUser();
u.promote();
console.log(u.isAdmin()); // true
// console.log(u.role); // ❌ Error: 'role' is protected
Parameter properties – skrót deklaracji pól
// TS shortcut: visibility modifiers in constructor params
class Person {
constructor(
public name: string,
private age: number,
public readonly id: number
) {}
info() { return `${this.name} (${this.id})`; }
}
const person = new Person('Ala', 30, 101);
console.log(person.info()); // "Ala (101)"
// console.log(person.age); // ❌ private
// person.id = 202; // ❌ readonly

odnośnie ramki “dla dociekliwych”, po dodaniu w kodzie:
user.setPassword(“wrongPassword”, “anotherSecurePassword”) // Old password is incorrect!
user.password = “wrongPassword”
user.setPassword(“wrongPassword”, “anotherSecurePassword”)
ta ostatnia zmiana hasła działa, tzn
Password updated successfully.
Old password is incorrect.
Password updated successfully.
Czy dzieje się tak, bo modyfikatory nie są “twardo” egzekwowane przed ES2022?
Czy jedynym lekarstwem jest używanie “prawdziwego” modyfikatora private, np. #password / this.#password?
Świetna pytanie i dokładnie tak to działa 😉 To, co widzisz, wynika z faktu, że private w TypeScript działa tylko na etapie kompilacji, a nie w runtime. Po wygenerowaniu JavaScriptu pole password jest zwykłą właściwością obiektu, więc można je nadpisać z zewnątrz, omijając logikę metody setPassword.
Dlatego po ręcznym przypisaniu:
kolejne wywołanie:
user.setPassword("wrongPassword", "anotherSecurePassword")działa poprawnie, bo warunek porównania już się zgadza.
Jeśli zależy nam na prawdziwej enkapsulacjito należy użyć prywatnych pól JavaScript:
które są rzeczywiście ukryte i nie da się ich zmodyfikować spoza klasy 🙂
Chyba, że to wynika z wykonywania skryptów przez wywołanie npx tsx;
google ai sugeruje, że ten sposób uruchomienia m.in nie sprawdza typów.
Dobry tip bo npx tsx faktycznie uruchamia kod bez pełnego sprawdzenia typów, więc może przepuścić błędy, które tsc by zgłosił. Dokumentacja tsx wprost mówi, że narzędzie nie wykonuje samodzielnie sprawdzania typów i zakłada, że robimy to osobno, np. przez tsc –noEmit albo w IDE.
Natomiast w tym przykładzie to nie tsx jest sednem problemu. Nawet gdybyś uruchomił kod po pełnym sprawdzeniu TypeScript, private w TypeScript i tak nie daje pełnej ochrony 🙂
W dokumentacji TypeScript znajdziemy ze jesli potrzebujemy pełnej prywatności dla pól to należy użyć mechanizmów takich jak private fields z # 🙂
https://www.typescriptlang.org/docs/handbook/2/classes.html#caveats