如何创建一个简单的打字稿元数据注释 [英] How to Create a Simple Typescript Metadata Annotation
问题描述
我有些字段在发送到服务器端之前需要进行格式化.
I have some fields that need to be formatted before sent to server-side.
因此,我想使用自定义序列化器来序列化我的打字稿类的某些字段,这将是理想的选择:
So, I would like to serialize some fields of my typescript classes using custom serializers, something like that would be ideal:
export class Person {
@serializeWith(MyDateSerializer)
private date: Date;
}
post(url, value) {
this.http.post(url, JSON.stringfy(value, (key, val) => {
if (//value has serializeWith annotation) {
return //serialize with custom serializer
}
}));
}
任何可以接受的方法都可以接受,欢迎任何帮助. 谢谢
Anything close to this would be acceptable, any help is welcome. Thanks
推荐答案
我的以下解决方案基于以下内容:
My solution below is built on top of:
- TypeScript Decorators
- Metadata spec (early stage/experimental)
先决条件:
- 在您的
tsconfig.json
或命令行中的TypeScript中启用Decorator和Decorator元数据支持:
- Enable Decorator and decorator metadata support in TypeScript in you
tsconfig.json
or on the command line:
tsconfig.json
{
"compilerOptions": {
"target": "es5", // you have to target es5+
"experimentalDecorators": true,
"emitDecoratorMetadata": true
// ....
}
// ...
}
-
安装
reflect-metadata
软件包
npm install --save-dev reflect-metadata
npm install --save-dev reflect-metadata
serializerWith
装饰器(工厂)
装饰器工厂是一种带有一个或多个参数并返回TypeScript在生成的JavaScript代码中使用的装饰器函数的东西.
serializerWith
Decorator (factory)
A decorator factory is something that takes one or many parameters and returns a decorator function that TypeScript uses in the generated JavaScript code.
我选择直接将序列化函数传递到我的装饰器工厂中,并使用metdata规范的reflect-metadata
实现将序列化器函数与该属性相关联.稍后,我将检索它并在运行时使用它.
I have chosen to directly pass the serialization function into my decorator factory and use the reflect-metadata
implementation of the metdata spec to associate the serializer function with the property. I will later retrieve it and use it at run-time.
function serializeWith(serializer: (input: any) => string) : (target: any, propertyKey: string) => void {
return function(target: any, propertyKey: string) {
// serialization here is the metadata key (something like a category)
Reflect.defineMetadata("serialization", serializer, target, propertyKey);
}
}
使用
给出此序列化器:
Use
Given this serializer:
function MyDateSerializer(value : any) : string {
console.log("MyDateSerializer called");
return "dummy value";
}
然后我们可以像这样应用装饰器工厂:
We can then apply the decorator factory like this:
import "reflect-metadata"; // has to be imported before any decorator which uses it is applied
class Greeter {
@serializeWith(MyDateSerializer)
public greeting : string;
constructor(message: string) {
this.greeting = message;
}
}
我们可以像这样获得并使用序列化器:
And we can get and use the serializer like this:
var greetingInstance = new Greeter("hi");
var serializerFunc : (input: any) => string = Reflect.getMetadata("serialization", greetingInstance, "greeting");
serializerFunc(greetingInstance.greeting);
样本
main.ts
import "reflect-metadata";
function serializeWith(serializer: (input: any) => string) : (target: any, propertyKey: string) => void {
return function(target: any, propertyKey: string) {
console.log("serializeWith called: adding metadata");
Reflect.defineMetadata("serialization", serializer, target, propertyKey);
}
}
function MyDateSerializer(value : any) : string {
console.log("MyDateSerializer called");
return "bla";
}
class Greeter {
@serializeWith(MyDateSerializer)
public greeting : string;
constructor(message: string) {
console.log("Greeter constructor");
this.greeting = message;
}
}
var greetingInstance = new Greeter("hi");
var serializerFunc : (input: any) => string = Reflect.getMetadata("serialization", greetingInstance, "greeting");
var serializedValue = serializerFunc(greetingInstance.greeting);
console.log(serializedValue);
输出
c:\code\tmp\lll>node build\main.js
serializeWith called: adding metadata
Greeter constructor
MyDateSerializer called
bla
这篇关于如何创建一个简单的打字稿元数据注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!