如何获取装饰器的原型?

How to get prototype for decorator?

提问人:Vlad 提问时间:11/17/2023 最后编辑:Vlad 更新时间:11/17/2023 访问量:13

问:

我有一个打字稿类:

class InnerClassA {
  property1: string;
  property2: number;
}

class InnerClassB {
  property3: boolean;
  property4: string;
}

class ABC {
  innerA: InnerClassA;
  innersB: InnerClassB[];
}

现在,我想向属性添加一些元数据。

为此,我创建了一个装饰器:

import 'reflect-metadata';

export const metadataKey = 'label';

export function Label(label: string): PropertyDecorator {
  return function (target: any, propertyKey: string) {
    Reflect.defineMetadata(metadataKey, label, target, propertyKey);
  };
}

然后我应用这个装饰器:

class InnerClassA {
  @Label('Name')
  property1: string;

  @Label('Age')
  property2: number;
}

class InnerClassB {
  @Label('Has a cat')
  property3: boolean;

  @Label('Cat name')
  property4: string;
}

class ABC {
  @Label('General info')
  innerA: InnerClassA;

  @Label('Pets')
  innersB: InnerClassB[];
}

现在我有来自后端的数据,我需要进行转换:

interface TreeNode {
  label: string;
  data: Array<TreeNode | LeafNode>;
}

interface LeafNode {
  label: string;
  value: any;
}

function transformObjectToTree(obj: any): Array<TreeNode | LeafNode> {
  const result: Array<TreeNode | LeafNode> = [];

  for (const [key, value] of Object.entries(obj)) {
    
    const label = Reflect.getMetadata(
      metadataKey,
      InnerClassA.prototype, // TODO: Problem is here, should be for each class
      key,
    );

    if (typeof value === 'object' && value !== null) {
      const subtree: TreeNode = {
        label: label || key,
        data: transformObjectToTree(value),
      };
      result.push(subtree);
    } else {
      const leaf: LeafNode = {
        label: label || key,
        value: value,
      };
      result.push(leaf);
    }
  }

  return result;
}

问题是我需要将 a 传递给方法,但我无法在运行时获取它。targetReflect.getMetadata

const data: ABC = this.service.getData();
const result = transformObjectToTree(data);

我尝试了以下选项:

const target = Reflect.getPrototypeOf(obj); // No luck
const target = Object.getPrototype(obj); // No luck
const target = obj.prototype; // No luck
const target = obj.__proto__; // No luck
const data: ABC = {
  innerA: {
      property1: "Mary",
      property2: "42",
    },
  innerB: [
    {
      property3: true,
      property4: "Jack",
    },
    {
      property3: true,
      property4: "Jim"
    }
  ]
};

const result = transformObjectToTree(data);

结果:

[
  {
    "label": "General info",
    "data":
    [
      { "label": "Name", "value": "Mary" },
      { "label": "Age", "value": 42 }
    ]
  },
  {
    "label": "Pets"
    "data":
    [
      {
         "label": "0",
         "data":
         [
            { "label": "Has a cat", "value": true },
            { "label": "Cat name", "value": "Jack" }
         ]
      },
      {
         "label": "1",
         "data":
         [
            { "label": "Has a cat", "value": true },
            { "label": "Cat name", "value": "Jim" }
         ]
      }
    ]
  }
]

如何解决?

TypeScript 反射 元数据 原型 装饰器

评论


答: 暂无答案