如何使用通用的枚举类扩展通用的接口?

时间:2019-05-16 10:30:11

标签: typescript typescript-generics

我正在使用一个库来序列化对象,它支持自定义转换器来序列化/反序列化数据。

为了对枚举执行此操作,您需要使用扩展以下接口的自定义转换器。

10:50 ~/.virtualenvs $ pip3 install django-tinymce --user
Looking in links: /usr/share/pip-wheels
Requirement already satisfied: django-tinymce in /home/UrosDobricic/.local/lib/python3.7/site-packages (2.8.0)

这是我目前拥有的:

export interface JsonCustomConvert<T> {
    serialize(data: T): any;
    deserialize(data: any): T;
}

问题显然是每个枚举都需要一个转换器。是否有任何方法可以在类上使用泛型类型对任何字符串索引的枚举进行此工作?

自从我学习该语言以来,到目前为止没有任何例子可以说明,任何尝试都将导致随机错误。

1 个答案:

答案 0 :(得分:3)

我们可以创建一个返回一个类的工厂函数。所有枚举的实现都是相同的,但是实际的枚举将作为参数传递给工厂函数:

import {
  JsonObject,
  JsonProperty,
  JsonConvert,
  JsonConverter,
  JsonCustomConvert,
} from "json2typescript";

enum A {
  a = "aa",
  b = "bb"
}

enum X {
  x = "xx",
  z = "zz"
}

function createConverter<T extends Record<keyof T, string | number>>(e: T){
  const reverseLookup = {} as  Record<T[keyof T], keyof T>
  for (const key of Object.keys(e) as Array<keyof T>) {
    reverseLookup[e[key]] = key;
  }
  @JsonConverter
  class EnumConverter implements JsonCustomConvert<T[keyof T]> {
    serialize(val: T[keyof T]): keyof T {
      return reverseLookup[val];
    }
    deserialize(val: keyof T): T[keyof T] {
      const possibleValidEnum = e[val];
      if (possibleValidEnum === undefined) {
        throw Error();
      }
      return possibleValidEnum as T[keyof T];
    }
  }
  return EnumConverter;
}


const XEnumConverter = createConverter(X);
const AEnumConverter = createConverter(A);

@JsonObject("User")
class User {
  @JsonProperty("aEnum", AEnumConverter)
  aEnum: A = A.a;
  @JsonProperty("xEnum", XEnumConverter)
  xEnum: X = X.x;
}

const jsonObj = {
  "aEnum": "a",
  "xEnum": "x"
};

let jsonConvert: JsonConvert = new JsonConvert();
let user: User = jsonConvert.deserializeObject(jsonObj, User);
console.log(user); // User {aEnum: "aa", xEnum: "xx"}

let r: User = jsonConvert.serializeObject(user);
console.log(r); // {aEnum: "a", xEnum: "x"}