In TypeScript worden toegangmodifiers gebruikt om de zichtbaarheid van eigenschappen en methoden in klassen te beperken:
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); // Fout: private is niet zichtbaar in afgeleide class } } const dog = new Dog('Sharik', 5, 'zoogdier'); console.log(dog.name); // OK // console.log(dog.kind); // Fout: protected // console.log(dog.age); // Fout: private
#field, maar dit is al een JS-specificatie en wordt anders gecompileerd.Vraag: Is het mogelijk om toegang te krijgen tot een private eigenschap van een TypeScript-class na compilatie naar JavaScript?
Antwoord: Ja, omdat private (en protected) slechts een controle door TypeScript zijn op compileertijd, na compilatie naar ES5 of ES6 blijft de privacy niet behouden, de eigenschappen blijven in het object en zijn toegankelijk via naam-toegang (bijvoorbeeld via object['privateProp']).
// JS-code na compilatie function Animal(name, age, kind) { this.name = name; this.age = age; this.kind = kind; } var dog = new Animal('Sharik', 5, 'zoogdier'); console.log(dog['age']); // 5 — toegang is alleen op TS-niveau niet toegestaan!
Verhaal
In een groot project rekende de ontwikkelaar op de onbereikbaarheid van private velden in runtime. Als gevolg hiervan werden vertrouwelijke gegevens per ongeluk in de logboeken opgenomen bij het serialiseren van een object (JSON.stringify), omdat de TS-typing niet beschermde tegen werkelijke toegang tot de velden.
Verhaal
In het project werd een mechanisme gerealiseerd voor het "uitbreiden" van class-instanties door dynamisch eigenschappen toe te voegen. Dynamisch toegevoegde eigenschappen overschreven private namen, en ze werden per ongeluk gemanipuleerd door externe code. De fout werd pas op de productie ontdekt, waarbij de privacy niet werd gewaarborgd.
Verhaal
Bij de migratie van JavaScript naar TypeScript begon het team protected te gebruiken, denkend dat dit beschermde tegen het gebruik van velden buiten afgeleide klassen. Maar een programmeur overschreef per ongeluk het protected-veld in runtime via
Object.assign, wat leidde tot een moeilijk te traceren bug. Dit was mogelijk omdat er geen runtime-inkapseling was.