Last active
December 21, 2022 02:35
-
-
Save zzpmaster/467749e99f7b1044eee7e5532de2a82f to your computer and use it in GitHub Desktop.
Watch for Object Changes with JavaScript by Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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