diff --git a/index.ts b/index.ts index e74a2c8..459b837 100644 --- a/index.ts +++ b/index.ts @@ -236,31 +236,34 @@ export function memoizeDecorator< >( options: Options = {}, ) { - 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) { + // 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; + } as FunctionToMemoize; + + return memoizedFunction; }; } diff --git a/readme.md b/readme.md index 6263a9a..6eb35aa 100644 --- a/readme.md +++ b/readme.md @@ -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 diff --git a/tsconfig.json b/tsconfig.json index ef8e4cd..a742837 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,6 @@ { "extends": "@sindresorhus/tsconfig", - "compilerOptions": { - "experimentalDecorators": true - }, + "compilerOptions": {}, "files": [ "index.ts" ],