@Deprecated
Less than 1 minute
@Deprecated
1. Create the annotation
deprecated.annotation.ts
import { AnnotationFactory } from '@aspectjs/common';
const af = new AnnotationFactory('aspectjs');
interface DeprecatedAnnotationOptions {
asError?: boolean | ((...args: unknown[]) => boolean);
message?: string;
}
export const Deprecated = af.create(function (
options?: DeprecatedAnnotationOptions | string,
) {});
As the annotation type is not specified, it can be used above classes, methods, attributes and parameters.
2. Create the aspect
deprecated.aspect.ts
import { AnnotationTarget } from '@aspectjs/common';
import { Aspect, Before, BeforeContext, on } from '@aspectjs/core';
import { Deprecated } from './deprecated.annotation';
@Aspect('deprecated')
export class DeprecatedAspect {
// log deprecated message only one per target
private readonly loggedTargets = new Set<AnnotationTarget>();
constructor(
// log level
private level: string = 'warn',
// current version of the program
private version?: number | string,
) {}
// or: @Before( on.any.withAnnotations(Deprecated))
@Before(
on.methods.withAnnotations(Deprecated),
on.classes.withAnnotations(Deprecated),
on.properties.withAnnotations(Deprecated),
on.properties.setter.withAnnotations(Deprecated),
on.parameters.withAnnotations(Deprecated),
)
logDeprecated(context: BeforeContext) {
// get the @Deprecated annotation
const deprecated = context.annotations(Deprecated).find()[0];
// get the arguments of the annotation
const options = deprecated.args[0];
// use the given deprecation message, or create a default one
const message =
typeof options === 'string'
? options
: options?.message ?? `Calling deprecated ${context.target.label}`;
const asError = typeof options === 'object' && options?.asError;
// Throw an error instead of log a warning ?
if (
asError === true ||
(typeof asError === 'function' && asError(this.version))
) {
throw new Error(`Calling deprecated ${context.target.label}`);
}
// log the message if not already logged
if (!this.loggedTargets.has(context.target)) {
(console as any)[this.level](
`Calling deprecated ${context.target.label}`,
);
this.loggedTargets.add(context.target);
}
}
}
3. Enable the aspect
aop.ts
import { getWeaver } from '@aspectjs/core';
import { DeprecatedAspect } from './deprecated.aspect';
getWeaver().enable(new DeprecatedAspect('error', '1.2.0'));
4. Use the aspect
hello.ts
import { Deprecated } from './deprecated.annotation';
@Deprecated()
export class Hello {
/**
* @deprecated Use {@link #sayHi()} instead
*/
@Deprecated({ asError: true })
sayHello() {
console.log('Hello world');
}
sayHi() {
console.log('Hey buddy');
}
sayGoodbye() {}
}