refactor(@angular/cli): use non-experimental decorators for internal memoize

With standard decorator support now available for use, the memoize decorator
has been updated to be a standard decorator instead of a TypeScript experimental
decorator. This change also removes the only usage of decorators within the
Angular CLI code itself. This change does not affect application code.
This commit is contained in:
Charles Lyding 2023-03-03 12:53:07 -05:00 committed by Douglas Parker
parent 17e168379e
commit 137949e8ff
2 changed files with 20 additions and 28 deletions

View File

@ -13,41 +13,34 @@
* *
* @see https://en.wikipedia.org/wiki/Memoization * @see https://en.wikipedia.org/wiki/Memoization
*/ */
export function memoize<T>( export function memoize<This, Args extends unknown[], Return>(
target: Object, target: (this: This, ...args: Args) => Return,
propertyKey: string | symbol, context: ClassMemberDecoratorContext,
descriptor: TypedPropertyDescriptor<T>, ) {
): TypedPropertyDescriptor<T> { if (context.kind !== 'method' && context.kind !== 'getter') {
const descriptorPropertyName = descriptor.get ? 'get' : 'value';
const originalMethod: unknown = descriptor[descriptorPropertyName];
if (typeof originalMethod !== 'function') {
throw new Error('Memoize decorator can only be used on methods or get accessors.'); throw new Error('Memoize decorator can only be used on methods or get accessors.');
} }
const cache = new Map<string, unknown>(); const cache = new Map<string, Return>();
return { return function (this: This, ...args: Args): Return {
...descriptor, for (const arg of args) {
[descriptorPropertyName]: function (this: unknown, ...args: unknown[]) { if (!isJSONSerializable(arg)) {
for (const arg of args) { throw new Error(
if (!isJSONSerializable(arg)) { `Argument ${isNonPrimitive(arg) ? arg.toString() : arg} is JSON serializable.`,
throw new Error( );
`Argument ${isNonPrimitive(arg) ? arg.toString() : arg} is JSON serializable.`,
);
}
} }
}
const key = JSON.stringify(args); const key = JSON.stringify(args);
if (cache.has(key)) { if (cache.has(key)) {
return cache.get(key); return cache.get(key) as Return;
} }
const result = originalMethod.apply(this, args); const result = target.apply(this, args);
cache.set(key, result); cache.set(key, result);
return result; return result;
},
}; };
} }

View File

@ -5,7 +5,6 @@
"module": "commonjs", "module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"noEmitOnError": true, "noEmitOnError": true,
"experimentalDecorators": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noImplicitOverride": true, "noImplicitOverride": true,
"isolatedModules": true, "isolatedModules": true,