{"record":{"id":"91e77ac42257d7b5","repo":"angular/angular-cli","slug":"memoize-decorator-can-only-be-used-on-methods-or-g","errorCode":null,"errorMessage":"Memoize decorator can only be used on methods or get accessors.","messagePattern":"Memoize decorator can only be used on methods or get accessors\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/utilities/memoize.ts","lineNumber":21,"sourceCode":" * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * A decorator that memoizes methods and getters.\n *\n * **Note**: Be cautious where and how to use this decorator as the size of the cache will grow unbounded.\n *\n * @see https://en.wikipedia.org/wiki/Memoization\n */\nexport function memoize<This, Args extends unknown[], Return>(\n  target: (this: This, ...args: Args) => Return,\n  context: ClassMemberDecoratorContext,\n) {\n  if (context.kind !== 'method' && context.kind !== 'getter') {\n    throw new Error('Memoize decorator can only be used on methods or get accessors.');\n  }\n\n  const cache = new Map<string, Return>();\n\n  return function (this: This, ...args: Args): Return {\n    for (const arg of args) {\n      if (!isJSONSerializable(arg)) {\n        throw new Error(\n          `Argument ${isNonPrimitive(arg) ? arg.toString() : arg} is JSON serializable.`,\n        );\n      }\n    }\n\n    const key = JSON.stringify(args);\n    if (cache.has(key)) {\n      return cache.get(key) as Return;\n    }\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/utilities/memoize.ts#L3-L39","documentation":"The `memoize` decorator (a TC39 decorator wrapping methods/getters) checks `context.kind` and only supports `'method'` and `'getter'` member kinds. Applying `@memoize` to any other kind (setter, field, or a plain function in a context where kind differs) is rejected at decoration time, since caching semantics only make sense for parameterless-ish calls and accessors.","triggerScenarios":"Decorating a class setter (`set foo(v)`), a class field, or another unsupported class member with `@memoize`, evaluated when the class is defined.","commonSituations":"Refactoring a getter into a setter while keeping the decorator; applying the decorator to a property intended as a lazily-computed value (should be a getter instead); copy-pasting the decorator onto the wrong member.","solutions":["Apply `@memoize` only to methods or `get` accessors.","If you need a cached property, convert the field to a `get` accessor: `@memoize get value() {...}`.","Remove the decorator from setters; caching a setter is not meaningful — cache the corresponding getter instead.","If memoizing a free function, wrap it manually with a Map-based cache instead of the decorator."],"exampleFix":"// before\nclass C {\n  @memoize set foo(v: string) { this._v = v; }\n}\n// after\nclass C {\n  @memoize get foo() { return computeFoo(); }\n  set foo(v: string) { this._v = v; }\n}","handlingStrategy":"type-guard","validationCode":"// At class-definition time, only decorate methods/getters:\nclass C {\n  @memoize\n  get value(): number { return expensive(); }\n}","typeGuard":"function supportsMemoize(ctx: ClassMemberDecoratorContext): boolean {\n  return ctx.kind === 'method' || ctx.kind === 'getter';\n}","tryCatchPattern":"// Decoration errors surface at class definition; wrap module evaluation if dynamic:\ntry {\n  const mod = await import('./decorated-module.js');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Memoize decorator can only be used')) {\n    console.error('Fix the @memoize target: use a method or getter.');\n  } else { throw e; }\n}","preventionTips":["Only place @memoize on methods or get accessors.","Never apply @memoize to setters, fields, or static initializers.","Convert lazily-computed fields to getters to use memoize.","Enable strict decorator typing so TypeScript flags misuse early."],"tags":["typescript","decorator","memoize","developer-error"],"backgroundTag":"invalid-decorator-target","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}