W TypeScript modyfikatory dostępu używane są do ograniczania zakresu widoczności właściwości i metod w klasach:
class Animal { public name: string; private age: number; protected kind: string; constructor(name: string, age: number, kind: string) { this.name = name; this.age = age; this.kind = kind; } } class Dog extends Animal { bark() { console.log(this.kind); // OK: protected // console.log(this.age); // Błąd: private nie widoczne w potomku } } const dog = new Dog('Szarik', 5, 'ssak'); console.log(dog.name); // OK // console.log(dog.kind); // Błąd: protected // console.log(dog.age); // Błąd: private
#field, ale to już specyfikacja JS i jest kompilowana inaczej.Pytanie: Czy można uzyskać dostęp do prywatnej właściwości klasy TypeScript po kompilacji do JavaScript?
Odpowiedź: Tak, ponieważ private (i protected) — to sprawdzenie TypeScript na etapie kompilacji, po kompilacji do ES5 lub ES6 prywatność nie jest zachowana, właściwości pozostają w obiekcie i są dostępne poprzez odwołanie się do nazwy właściwości (na przykład poprzez object['privateProp']).
// Kod JS po kompilacji function Animal(name, age, kind) { this.name = name; this.age = age; this.kind = kind; } var dog = new Animal('Szarik', 5, 'ssak'); console.log(dog['age']); // 5 — dostęp jest tylko na poziomie TS!
Historia
W dużym projekcie programista polegał na fakcie niedostępności prywatnych pól w czasie działania. W wyniku przesłania obiektu za pomocą serializacji (JSON.stringify) do logów przypadkowo trafiły poufne dane, ponieważ typizacja TS nie chroniła przed rzeczywistym dostępem do pól.
Historia
W projekcie wdrożono mechanizm "rozszerzania" instancji klas poprzez dynamiczne dodawanie właściwości. Dynamicznie dodane właściwości nadpisywały prywatne nazwy, a ich zmiana przypadkowo została dokonana przez zewnętrzny kod. Błąd został wykryty dopiero na produkcji, a prywatność nie była zapewniona.
Historia
Podczas migracji z JavaScript do TypeScript zespół zaczął używać protected, sądząc, że chroni to przed użyciem pól poza klasami potomnymi. Jednak programista przez
Object.assignprzypadkowo nadpisał pole protected w czasie działania i otrzymał trudny do wykrycia błąd. To stało się możliwe, ponieważ nie było inkapsulacji w czasie działania.