json - 如何创建简单的 Typescript 元数据注释

标签 json serialization typescript angular decorator

我有一些字段需要在发送到服务器端之前进行格式化。

所以,我想使用自定义序列化器序列化我的 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
  2. Metadata spec (early stage/experimental)

先决条件:

  1. tsconfig.json 或命令行中启用 TypeScript 中的装饰器和装饰器元数据支持:

tsconfig.json

{
    "compilerOptions": {
        "target": "es5", // you have to target es5+
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
        // ....
    }
    // ...
}
  1. 安装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);

示例

ma​​in.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

关于json - 如何创建简单的 Typescript 元数据注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38085883/

相关文章:

javascript - React - 动态表中的 OnChange 调用会产生 Uncaught TypeError

javascript - 从一键 JSON jQuery 输出各个值

c# - MongoDB 序列化 Dictionary<MyEnum,object>

ruby-on-rails - has_many 通过事件模型序列化器 Rails API 中的关系

python - 为什么一些 numpy 数据类型是 JSON 可序列化的,而另一些则不是?

angular - 在 Angular 6 中使用默认属性输入

typescript - 如何检查角度 8 中的响应或状态代码以将文件上传到 S3 预签名 URL 且状态代码为 200

java - Json/字符串/字节转换操作(发送字节到socket)

json - 将 JSON 字符串转换为 Erlang 记录的库

javascript - 检查json数据的值