_ _ _ __ | |__ | | ___ __ _ | '_ \| '_ \| |/ _ \ / _` | | |_) | | | | | (_) | (_| | | .__/|_| |_|_|\___/ \__, | |_| ...2024-05-23 |___/ A neat thing with property decorators in typescript. Say you're working on a larger project where you'd like to keep knowledge duplication at a minimum and also local to its user. For example, you might want to register some meta-data which is to be used for another purpose, and you want this knowledge available before you've used it. That sounds weird, sorry, here's a concrete example. Say you're doing an angular application which uses "services" to fetch data. These services must call endpoints. At the same time, you'd like, for whatever reason, at program start time, to know exactly which endpoints can be called, and also, which services call them. Here's one way of doing it in TypeScript (I write test.js to get highlighting) test.js: const accessMap = {}; function mkGet(l, endpoint) { for(const f of l) { (accessMap[f] || (accessMap[f] = [])).push(endpoint); } return function(target: Object, key: string) { Object.defineProperty(target, key, { value: (params: Record)=>{ let u = endpoint; for(key in params) { u = u.replace( new RegExp(`:${key}`), params[key]); } console.log('Calling '+u); } }); }; } export function getAccessMap() { return accessMap; } // A service using it: class TestService { @mkGet(['ItemAdministation', 'ItemDetails'], '/items/:itemId') private getItemById @mkGet(['itemList', 'ItemAdministation'], '/items/') private getItemList @mkGet(['itemList'], '/itemLocations/') private getLocations async getItemsAndLocations() { const allItems = await this.getItemList(); const locations = await this.getLocations(); // Do something with them } async getItemDetails(itemId) { const rawItem = await this.getItemById( {itemId} ); // Do something with it } } console.log(JSON.stringify(getAccessMap(), null, 4)); new TestService().getItemDetails(123); Transpiling and output in bash: tsc --lib dom,ES2015 --experimentalDecorators test.ts node test.js { "ItemAdministation": [ "/items/:itemId", "/items/" ], "ItemDetails": [ "/items/:itemId" ], "itemList": [ "/items/", "/itemLocations/" ] } Calling /items/123