typescript - 如何在 Typescript 中组合多个属性装饰器?
问题描述
我有一个Template
带有属性的类,该属性具有来自和的_id
装饰器class-transformer
typed-graphql
import {classToPlain, Exclude, Expose, plainToClass, Type } from 'class-transformer';
import { ExposeToGraphQL } from '../../decorators/exposeToGraphQL';
import { Field, ID, MiddlewareInterface, NextFn, ObjectType, ResolverData } from 'type-graphql';
import { getClassForDocument, InstanceType, prop, Typegoose } from 'typegoose';
/**
* Class
* @extends Typegoose
*/
@Exclude()
@ObjectType()
class Template extends Typegoose {
// @Expose and @Type should be both covered by ExposeToGraphQL
// @Expose()
@Type(() => String)
@ExposeToGraphQL()
@Field(() => ID)
public _id?: mongoose.Types.ObjectId;
}
现在我尝试将这两者组合成一个新的自定义属性装饰器:
/**
*
*/
import { Expose } from 'class-transformer';
import 'reflect-metadata';
const formatMetadataKey: Symbol = Symbol('ExposeToGraphQL');
function ExposeToGraphQL() {
console.log('ExposeToGraphQL');
return Expose();
}
function getExposeToGraphQL(target: any, propertyKey: string) {
console.log('getExposeToGraphQL');
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
export {
ExposeToGraphQL,
getExposeToGraphQL,
};
如果我只返回 的结果,自定义装饰器就可以工作Expose()
,但我不知道如何组合@Expose
和@Type
in @ExposeToGraphQL()
。
解决方案
import { Expose, Type, TypeOptions, ExposeOptions } from 'class-transformer';
/**
* Combines @Expose then @Types decorators.
* @param exposeOptions options that passes to @Expose()
* @param typeFunction options that passes to @Type()
*/
function ExposeToGraphQL(exposeOptions?: ExposeOptions, typeFunction?: (type?: TypeOptions) => Function) {
const exposeFn = Expose(exposeOptions);
const typeFn = Type(typeFunction);
return function (target: any, key: string) {
typeFn(target, key);
exposeFn(target, key);
}
}
然后您可以按如下方式使用该装饰器:
class Template extends Typegoose {
@ExposeToGraphQL(/*exposeOptions*/ undefined, /*typeFunction*/ () => String)
@Field(() => ID)
public _id?: mongoose.Types.ObjectId;
}
您可以在此链接中找到装饰器的官方文档。
@Expose
并且@Type()
基本上是装饰工厂。装修厂的主要目的:
- 它返回一个函数
- 该函数将在运行时调用(在
Template
定义类之后,在本例中为 ),并带有 2 个参数:- 类原型 (
Template.prototype
) - 装饰器附加到 (
_id
) 的属性的名称。
- 类原型 (
如果两个或多个装饰器附加到同一个属性(称为装饰器组合),它们的评估如下:
- 工厂函数的执行顺序与它们在代码中编写的顺序相同
- 工厂函数返回的函数按相反的顺序执行
推荐阅读
- java - 具有多个构造函数的最终成员
- python - Mac 上的 MySQL 和 Django - 未加载 libssl.1.0.0.dylib
- panel - 如何从 CAPL 更改 CANalyzer 面板中开关/指示器元素的路径图像属性?
- c# - 在 C# 中比较字典中的数组
- xquery - eXist-db 通过 controller.xml 将参数传递给模板(URL 映射)
- javascript - node-soap 结果是深层嵌套对象而不是普通结果
- python - 使用 Numpy 查找百分比变化
- java - 不兼容的类型需要 int 但发现为 void
- java - 在Java中递归调用具有多层父子的树状结构
- mongodb - 在 Spring Boot Mongo DB 运行时更改文档名称