Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,31 +236,34 @@ export function memoizeDecorator<
>(
options: Options<FunctionToMemoize, CacheKeyType> = {},
) {
const instanceMap = new WeakMap();

return (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor,
): void => {
const input = target[propertyKey]; // eslint-disable-line @typescript-eslint/no-unsafe-assignment
target: FunctionToMemoize,
context: ClassMethodDecoratorContext,
): FunctionToMemoize | void => {
if (context.kind !== 'method') {
throw new TypeError('The decorator can only be applied to methods');
}

if (typeof input !== 'function') {
if (typeof target !== 'function') {
throw new TypeError('The decorated value must be a function');
}

delete descriptor.value;
delete descriptor.writable;
const instanceMap = new WeakMap();

descriptor.get = function () {
const memoizedFunction = function (this: any, ...arguments_: Parameters<FunctionToMemoize>) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
if (!instanceMap.has(this)) {
const value = memoize(input, options) as FunctionToMemoize;
const value = memoize(target, options);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
instanceMap.set(this, value);
return value;
}

return instanceMap.get(this) as FunctionToMemoize;
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const memoized = instanceMap.get(this) as FunctionToMemoize;
return memoized.apply(this, arguments_) as ReturnType<FunctionToMemoize>;
} as FunctionToMemoize;

return memoizedFunction;
};
}

Expand Down
6 changes: 3 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ Returns a [decorator](https://github.com/tc39/proposal-decorators) to memoize cl

Notes:

- Only class methods and getters/setters can be memoized, not regular functions (they aren't part of the proposal);
- Only [TypeScript’s decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#parameter-decorators) are supported, not [Babel’s](https://babeljs.io/docs/en/babel-plugin-proposal-decorators), which use a different version of the proposal;
- Being an experimental feature, they need to be enabled with `--experimentalDecorators`; follow TypeScript’s docs.
- Only class methods can be memoized, not regular functions (they aren't part of the proposal);
- Requires TypeScript 5.0+ with stage 3 decorators (without `--experimentalDecorators`);
- For older experimental decorators support, use `memoize@10`.

#### options

Expand Down
4 changes: 1 addition & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"extends": "@sindresorhus/tsconfig",
"compilerOptions": {
"experimentalDecorators": true
},
"compilerOptions": {},
"files": [
"index.ts"
],
Expand Down