如何创建简单的 Typescript 元数据注释
Posted
技术标签:
【中文标题】如何创建简单的 Typescript 元数据注释【英文标题】:How to Create a Simple Typescript Metadata Annotation 【发布时间】:2016-10-31 08:26:51 【问题描述】:我有一些字段需要在发送到服务器端之前进行格式化。
所以,我想使用自定义序列化器序列化我的 typescript 类的一些字段,这样会很理想:
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
));
任何与此相近的东西都是可以接受的,欢迎任何帮助。 谢谢
【问题讨论】:
【参考方案1】:我下面的解决方案建立在:
-
TypeScript Decorators
Metadata spec (early stage/experimental)
先决条件:
-
在您的
tsconfig.json
或命令行中启用 TypeScript 中的装饰器和装饰器元数据支持:
tsconfig.json
"compilerOptions":
"target": "es5", // you have to target es5+
"experimentalDecorators": true,
"emitDecoratorMetadata": true
// ....
// ...
安装reflect-metadata
包
npm install --save-dev reflect-metadata
serializerWith
装饰者(厂)
装饰器工厂是接受一个或多个参数并返回 TypeScript 在生成的 javascript 代码中使用的装饰器函数的东西。
我选择将序列化函数直接传递到我的装饰器工厂,并使用元数据规范的reflect-metadata
实现将序列化函数与属性相关联。我稍后会检索它并在运行时使用它。
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);
使用
鉴于此序列化程序:
function MyDateSerializer(value : any) : string
console.log("MyDateSerializer called");
return "dummy value";
然后我们可以像这样应用装饰器工厂:
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;
我们可以像这样获取和使用序列化器:
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
【讨论】:
以上是关于如何创建简单的 Typescript 元数据注释的主要内容,如果未能解决你的问题,请参考以下文章
具有复制属性的类方法的元数据在更改源类的元数据时发生更改 - Typescript