Skip to content

Instantly share code, notes, and snippets.

@RomkeVdMeulen
Last active June 26, 2020 14:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save RomkeVdMeulen/e45ee89ce848e7fda140635a4d29892b to your computer and use it in GitHub Desktop.
Save RomkeVdMeulen/e45ee89ce848e7fda140635a4d29892b to your computer and use it in GitHub Desktop.
How to change instance properties through decorators in TypeScript: http://romkevandermeulen.nl/2018/01/24/typescript-property-decorators.html
function makePropertyMapper<T>(prototype: any, key: string, mapper: (value: any) => T) {
const values = new Map<any, T>();
Object.defineProperty(prototype, key, {
set(firstValue: any) {
Object.defineProperty(this, key, {
get() {
return values.get(this);
},
set(value: any) {
values.set(this, mapper(value));
},
enumerable: true,
});
this[key] = firstValue;
},
enumerable: true,
configurable: true,
});
}
function exampleDecorator(multiplier: number) {
return function(target: any, key: string) {
makePropertyMapper(target, key, (value: number) => {
return value * multiplier;
});
};
}
class Example {
@exampleDecorator(3)
myNumber: number;
@exampleDecorator(3)
withInitializer = 2;
}
const example = new Example();
console.log(example.myNumber); // undefined
console.log(Object.keys(example).includes("myNumber")); // false
console.log(example.withInitializer); // 6
console.log(Object.keys(example).includes("withInitializer")); // true
example.myNumber = 3;
console.log(example.myNumber); // 9
console.log(Object.keys(example).includes("myNumber")); // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment