Created
November 24, 2020 23:13
-
-
Save lygaret/0a7878d34df66a1dc32a2419ef178c05 to your computer and use it in GitHub Desktop.
typescript dynamic memoization (rspec let)
This file contains hidden or 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
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