class-decorator
class-decorator is typescript decorator framework.
Installing
npm i reflect-metadata @quicker-js/class-decorator
#or
yarn add reflect-metadata @quicker-js/class-decorator
Example Usage
The following examples contain basic usage methods. For more high-level usage methods, please refer to the test
directory.
Create class decorator
Create custom metadata file or use ClassMetadata
, custom metadata must use the ClassMetadata
extension.
entity-metadata.ts
export class EntityMetadata<
T = EntityMetadataOption
> extends ClassMetadata<T> {}
export interface EntityMetadataOption {
readonly title?: string;
readonly description?: string;
}
Create decorator file.
// import class-decorator
import { ClassMirror } from '@quicker-js/class-decorator';
// import entity-metadata.ts
import { EntityMetadata } from './entity-metadata';
// The decorator can be used in two ways.
export function Entity<T extends Function>(target: T): T | void;
export function Entity(title: string, description: string): ClassDecorator;
export function Entity<T extends Function>(
...args: unknown[]
): T | void | ClassDecorator {
if (args.length === 2) {
const [title, description] = args as [string, string];
return ClassMirror.createDecorator(
new EntityMetadata({
title,
description,
})
);
} else {
return ClassMirror.createDecorator(new EntityMetadata(null))(args[0] as T);
}
}
Create any class file, use @Entity
or @Entity(...)
decorator.
@Entity
class Foo {}
// or
@Entity({title: 'Bar', description: 'Class Bar'})
class Bar {}
Use ClassMirror.reflect
get metadata.
import {ClassMirror} from "./index";
var reflect1 = ClassMirror.reflect(Foo);
var reflect2 = ClassMirror.reflect(Bar);
console.log(reflect1.metadata) // Set<EntityMetadata>
console.log(reflect2.metadata) // Set<EntityMetadata>
Create property decorator
Create custom metadata file or use PropertyMetadata
, custom metadata must use the PropertyMetadata
extension.
exclude-metadata.ts
import { PropertyMetadata } from '@quicker-js/class-decorator';
/**
* @class ExcludeMetadata
*/
export class ExcludeMetadata<
T = ExcludeMetadataOption
> extends PropertyMetadata<T> {}
export interface ExcludeMetadataOption {
readonly toPlainOnly?: boolean;
readonly toClassOnly?: boolean;
}
Create custom property decorator
use PropertyMirror.createDecorator
create property decorator.
import { ExcludeMetadata, ExcludeMetadataOption } from './exclude-metadata';
import { PropertyMirror } from '@quicker-js/class-decorator';
// The decorator can be used in two ways.
export function Exclude(target: Object, propertyKey: string | symbol): void;
export function Exclude(option: ExcludeMetadataOption): PropertyDecorator;
export function Exclude(...args: unknown[]): void | PropertyDecorator {
if (args.length === 1) {
return PropertyMirror.createDecorator(
new ExcludeMetadata(args[0] as ExcludeMetadataOption)
);
} else {
const [target, propertyKey] = args as [Object, string | symbol];
return PropertyMirror.createDecorator(new ExcludeMetadata(null))(
target,
propertyKey
);
}
}
Create any class file, use @Exclude
or @Exclude(...)
decorator.
import {Exclude} from "your decoraror path"
class Foo {
@Exclude
public id: string;
@Exclude({toPlainOnly: true})
public name: string;
@Exclude
public static age: number;
}
Use PropertMirror.reflect
or ClassMirror.reflect
get metadata.
import {ClassMirror, PropertyMirror} from "./index";
// use ClassMirror get metadata.
const reflectClass = ClassMirror.reflect(Foo);
reflectClass.getMirror('id', false) // PropertyMirror<PropertyMetadata>
reflectClass.getMirror('age', false) //PropertyMirror<PropertyMetadata>
// use PropertyMirror get metadata.
const refect1 = PropertyMirror.reflect(Foo, 'id', false); // PropertyMirror<PropertyMetadata>
const refect2 = PropertyMirror.reflect(Foo, 'age', true); // PropertyMirror<PropertyMetadata>
console.log(refect1.metadata) // Set<ExcludeMetadata>
console.log(refect2.metadata) // Set<ExcludeMetadata>
// id: string
console.log(refect1.getDesignType()) // String
// age: number
console.log(refect2.getDesignType()) // Number
Create method decorator
Create custom metadata file or use MethodMetadata
, custom metadata must use the MethodMetadata
extension.
request-metadata.ts
import { MethodMetadata } from '@quicker-js/class-decorator';
/**
* @class RequestMetadata
*/
export class RequestMetadata<T = MetadataOption> extends MethodMetadata<T> {}
export interface RequestMetadataOption {
readonly path?: string;
readonly method?: string;
}
Create custom method decorator
use MethodMirror.createDecorator
create method decorator.
import { RequestMetadata, RequestMetadataOption } from './request-metadata';
import { MethodMirror } from '@quicker-js/class-decorator';
// Unlike the previous case, the decorator has only one use,but it can also be used in two ways, You must add your own implementation logic.
export function Request(metadata: RequestMetadataOption): MethodDecorator {
return MethodMirror.createDecorator(new RequestMetadata(metadata));
}
Create any class file, use@Request(...)
decorator.
import {Request} from "your decoraror path"
class Foo {
@Request({path: '/', method: 'post'})
public zoo(): string {
return 'zoo';
}
@Request({path: '/', method: 'post'})
public static bar(): number {
return 1;
}
}
Use Method.reflect
or ClassMirror.reflect
get metadata.
import {ClassMirror, PropertyMirror} from "./index";
// use ClassMirror get metadata.
const reflectClass = ClassMirror.reflect(Foo);
reflectClass.getMirror('zoo', false) // MethodMirror<MethodMetadata>
reflectClass.getMirror('bar', false) // MethodMirror<MethodMetadata>
// use MethodMirror get metadata.
const refectMethod1 = MethodMirror.reflect(Foo, 'zoo', false); // MethodMirror<MethodMetadata>
const refectMethod2 = MethodMirror.reflect(Foo, 'bar', true); // MethodMirror<MethodMetadata>
// Use function reflect metadata
MethodMirror.reflect(Foo, Foo.bar, true); // MethodMirror<MethodMetadata>
// Instance use Function reflect metadata
const foo = new Foo();
MethodMirror.reflect(Foo, Foo.zoo, false); // MethodMirror<MethodMetadata>
// Get method parameter metadata mirrors.
console.log(refectMethod1.parameters); // Map<number, ParameterMirror>
console.log(refectMethod2.parameters); // Map<number, ParameterMirror>
//Get reflect medatadata.
console.log(refectMethod1.metadata); // Set<MethodMetadata>
console.log(refectMethod2.metadata); // Set<MethodMetadata>
// Get parameters type
console.log(refectMethod1.getDesignParamTypes()); // []
console.log(refectMethod2.getDesignParamTypes()); // []
// Get Return type
console.log(refectMethod1.getReturnType()); // String
console.log(refectMethod2.getReturnType()); // Number
Create parameter decorator
Create custom metadata file or use ParameterMetadata
, custom metadata must use the ParameterMetadata
extension.
param-metadata.ts
import { ParameterMetadata } from '@quicker-js/class-decorator';
/**
* @class ParamMetadata
*/
export class ParamMetadata<T = MetadataOption> extends ParameterMetadata<T> {}
export interface ParamMetadataOption {
readonly path: string;
}
Create custom parameter decorator
use ParameterMirror.createDecorator
create parameter decorator.
import { ParamMetadata, ParamMetadataOption } from './param-metadata';
import { ParameterMirror } from '@quicker-js/class-decorator';
// The decorator can be used in two ways.
export function Param(target: Object, propertyKey: string | symbol, parameterIndex: number): void;
export function Param(option: MetadataOption): ParameterDecorator;
export function Param(...args: unknown[]): ParameterDecorator | void {
if (args.length === 1) {
const [option] = args as [MetadataOption];
return ParameterMirror.createDecorator(new Metadata(option));
} else {
const [target, propertyKey, parameterIndex] = args as [
Object,
string | symbol,
number
];
return ParameterMirror.createDecorator(new Metadata(null))(
target,
propertyKey,
parameterIndex
);
}
}
Create any class file, use @Param
or @Param(...)
decorator.
import {Exclude} from "your decoraror path";
import {Request} from "your decoraror path";
class Foo {
public constructor(
@Param({ path: 'constructor', method: 'post' }) public path: string,
@Param public index: number
) {}
@Request({path: '/', method: 'post'})
public zoo(@Param test: Number, @Param({path: '/'}) path: string): string {
return 'zoo';
}
public static bar(@Param test: Object, @Param({path: '/'}) path: string): number {
return 1;
}
}
Use ParameterMirror.reflect
or ParameterMirror.reflect
get metadata.
import {ClassMirror, MethodMirror, ParameterMirror} from "./index";
// use ClassMirror get metadata.
const reflectClass = ClassMirror.reflect(Foo);
reflectClass.getMirror('zoo', false) // MethodMirror<MethodMetadata>
reflectClass.getMirror('bar', false) // MethodMirror<MethodMetadata>
// use MethodMirror get metadata.
const refectMethod1 = MethodMirror.reflect(Foo, 'zoo', false); // MethodMirror<MethodMetadata>
const refectMethod2 = MethodMirror.reflect(Foo, 'bar', true); // MethodMirror<MethodMetadata>
// Get parameters type
console.log(refectMethod1.getDesignParamTypes()); // [Number, String]
console.log(refectMethod2.getDesignParamTypes()); // [Object, String]
// Get method parameter metadata mirrors, you can find metadata in parameters.
console.log(refectMethod1.parameters); // Map<number, ParameterMirror>
console.log(refectMethod2.parameters); // Map<number, ParameterMirror>
// Find 1st parameter metadata
const parameterMirror1 = refectMethod1.parameters.get(0); // ParameterMirror<ParameterMetadata>
// Find 2nd parameter metadata
const parameterMirror2 = refectMethod1.parameters.get(1); // ParameterMirror<ParameterMetadata>
// or
ParameterMirror.reflect(Foo, 'zoo', 0, false); // ParameterMirror<ParameterMetadata>
ParameterMirror.reflect(Foo, 'bar', 0, true); // ParameterMirror<ParameterMetadata>
parameterMirror1.getDesignParamType(); // Number
parameterMirror2.getDesignParamType(); // String
parameterMirror1.metadata // Set<ParameterMetadata>
parameterMirror2.metadata // Set<ParameterMetadata>
// If it is a parameter decorator of a constructor, you need to obtain metadata through the following methods
console.log(reflectClass.parameters); // Map<number, ParameterMirror>;
const parameterMirror3 = reflectClass.parameters.get(0) // ParameterMirror
const parameterMirror4 = reflectClass.parameters.get(1) // ParameterMirror
parameterMirror3.metadata // Set<ParameterMetadata>
parameterMirror4.metadata // Set<ParameterMetadata>
parameterMirror3.getDesignParamType(); // String
parameterMirror4.getDesignParamType(); // Number
Documentation
Issues
Create issues in this repository for anything related to the Class Decorator. When creating issues please search for existing issues to avoid duplicates.
License
Licensed under the MIT License.