Skip to content

Instantly share code, notes, and snippets.

@lygaret
Created November 24, 2020 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lygaret/0a7878d34df66a1dc32a2419ef178c05 to your computer and use it in GitHub Desktop.
Save lygaret/0a7878d34df66a1dc32a2419ef178c05 to your computer and use it in GitHub Desktop.
typescript dynamic memoization (rspec let)
type MemoProps<T> = { [P in keyof T]: (this: T) => T[P] }
export const MemoProto = {
clone: function () {
return this.define({});
},
define: function define<T>(this: T & {}, props: MemoProps<T>): MemoState<T> {
// share the prototype, so we can nest but still destroy
const update = Object.create(this);
// define memoized versions of the incoming props
for (let key in props) {
let value: any;
let executed = false;
Object.defineProperty(update, key, {
get: () => {
if (!executed) {
value = props[key].call(this);
executed = true;
}
return value;
},
enumerable: true,
});
}
// return the new object with fallback in the prototype chain
return update;
}
};
export type MemoState<T> = T & {
clone: (this: T) => MemoState<T>,
define: <U>(this: T & {}, p: MemoProps<U>) => MemoState<T & U>
};
export const Memo: MemoState<{}> = Object.create(MemoProto);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment