前言

关键字
reflect-metadata

参考资料

  • reflect-metadata 库:链接
  • Reflect Metadata《深入理解TypeScript》:链接
  • 「es6 知识库」符号:链接

    notes

了解 reflect-metadata 库的基本使用。
使用 reflect-metadata 库,优化 3-4. 装饰器练习

reflect-metata

  • 设置元数据:@Reflect.metadata(metadataKey, metadataValue)
  • 读取元数据:Reflect.getMetadata(metadataKey, target)Reflect.getMetadata(metadataKey, target, propertyKey)
  • 判断元数据是否存在:Reflect.hasMetadata(metadataKey, target)Reflect.hasMetadata(metadataKey, target, propertyKey)

更多 api 见:链接

codes

  1. import "reflect-metadata";
  2. @Reflect.metadata("inClass", "A")
  3. class Test {
  4. @Reflect.metadata("inMethod", "B")
  5. public hello(): string {
  6. return "hello world";
  7. }
  8. @Reflect.metadata("prop", "test...")
  9. test: string = "123";
  10. }
  11. const t = new Test();
  12. console.log(Reflect.getMetadata("inClass", Test)); // => A
  13. console.log(Reflect.getMetadata("inMethod", t, "hello")); // => B
  14. console.log(Reflect.getMetadata("prop", t, "test")); // => test...

**const t = new Test()**
如何通过实例 t 获取到实例的构造器 Test

  • t.__proto__.constructor === Test
  • Object.getPrototypeOf(t).constructor === Test
  1. import "reflect-metadata";
  2. const metadataKey = Symbol("description");
  3. // 添加元数据
  4. export function descriptor(description: string) {
  5. return Reflect.metadata(metadataKey, description);
  6. }
  7. // 打印描述信息
  8. export function printObj(obj: any) {
  9. const cons = obj.__proto__.constructor;
  10. // 打印类元信息
  11. if (Reflect.hasMetadata(metadataKey, cons)) console.log(Reflect.getMetadata(metadataKey, cons));
  12. else console.log(cons.name);
  13. // 打印属性元信息
  14. for (const key in obj) {
  15. if (Reflect.hasMetadata(metadataKey, obj, key))
  16. console.log(
  17. `\t${Reflect.getMetadata(metadataKey, obj, key)}: ${obj[key]}`
  18. );
  19. else console.log(`\t${key}: ${obj[key]}`);
  20. }
  21. }

const metadataKey = Symbol("description")
使用符号,防止出现元数据的 key 发生冲突。

  1. import { descriptor, printObj } from "./Descriptors";
  2. @descriptor("文章")
  3. class Article {
  4. @descriptor("标题")
  5. title: string;
  6. @descriptor("内容")
  7. content: string;
  8. @descriptor("日期")
  9. date: Date;
  10. }
  11. const ar = new Article();
  12. ar.title = "abc";
  13. ar.content = "123";
  14. ar.date = new Date();
  15. printObj(ar);

image.png

  1. import { descriptor, printObj } from "./Descriptors";
  2. @descriptor("用户")
  3. class User {
  4. @descriptor("账号")
  5. loginId: string;
  6. @descriptor("密码")
  7. loginPwd: string;
  8. @descriptor("用户名")
  9. name: string = "dahuyou";
  10. gender: "男" | "女" = "男";
  11. }
  12. const u = new User();
  13. u.loginId = "abc";
  14. u.loginPwd = "123";
  15. printObj(u);

image.png