Skip to content

Instantly share code, notes, and snippets.

@zzpmaster
Last active December 21, 2022 02:35
Show Gist options
  • Save zzpmaster/467749e99f7b1044eee7e5532de2a82f to your computer and use it in GitHub Desktop.
Save zzpmaster/467749e99f7b1044eee7e5532de2a82f to your computer and use it in GitHub Desktop.
Watch for Object Changes with JavaScript by Typescript
// Event Source
type propEvent<Type> = {
on<Key extends string & keyof Type>(
eventName: `${Key}Changed`,
callback: (newValue: Type[Key]) => void): void;
};
function makeWatchedObject<Type>(obj: Type): Type & propEvent<Type> {
const cbMap = new Map<string, Function>();
var proxy = new Proxy({
...obj,
on<Key extends string & keyof Type>(eventName: `${Key}Changed`, callback: (newValue: Type[Key]) => void): void {
const name = eventName.replace("Changed", "");
cbMap.set(name, callback);
},
}, {
set: function (target, propKey: string, value) {
const fn = cbMap.get(propKey);
fn && fn(value);
return Reflect.set(target, propKey, value);
}
})
return proxy;
}
// how to Use
const obj = makeWatchedObject({
firstName: 'Aaron',
age: 36
});
// newValue type is string
obj.on('firstNameChanged', (newValue) => {
console.log('name changed ->', newValue);
});
// newAge type is number
obj.on('ageChanged', (newAge) => {
console.log('age changed ->', newAge);
});
obj.firstName = 'Zhang';
obj.age = 25;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment