如何创建以“ _”开头的属性名称为基础,将所有类属性设置为不可枚举的Typescript装饰器?

如何获取Typescript类修饰器以调用将“ _”开头的任何属性或方法设置为不可枚举的属性的方法(本质上将其私有化以进行序列化)?

想象一下,有一个类是基类,我的应用程序中的所有其他类都将从该类扩展:

class Base {
     constructor(data: any){
        Object.assign(this,data)
     }

     _setNonEnumerableProperties(){
        Object.keys(this).forEach(key => {
            if(key[0] === '_')
                Object.defineProperty(this,key,{ enumerable: false })
        })
     }
}

然后我有一个类似的User类:

@nonEnumerablePrivateMembers
class User extends Base {
     public name: string
     public email: string
     private _active: boolean
}

然后我创建并用JSON字符串化一个User实例,如下所示:

const user = new User({name: 'John',email: 'john@example.com',_active: false})
const jsonUser = JSON.stringify(user)
console.log(jsonUser)

我希望输出是这样:

{ "name": "John","email": "john@example.com" }

不是这个:

{ "name": "John","email": "john@example.com","_active": false }

请注意,它不包含_active属性。

我需要知道如何编写nonEnumerablePrivateMembers装饰器,该装饰器将在扩展类的新实例上在基类上调用_setNonEnumerableProperties方法。

有什么建议吗?

xvgzxvgzxvgz 回答:如何创建以“ _”开头的属性名称为基础,将所有类属性设置为不可枚举的Typescript装饰器?

重写构造函数似乎按预期工作:

interface Class<T> {
  new(...args: any[]): T
}

function nonEnumerablePrivateMembers<T extends Class<Base>>(cls: T): T {
  return class extends cls {
    constructor(...args: any[]) {
      super(...args);
      this._setNonEnumerableProperties();
    }
  }
}

Playground

,

我确定具有更好TypeScript技能的人可以将其修改为更简洁的方法,但是基于TypeScript decorator docs,您可以看到类似这样的内容:

function fixEnumerables<T extends { new (...args: any[]): {} }>(
  constructor: T
) {
  return class extends constructor {
    constructor(...data: any[]) {
      super(data);
      Object.assign(this,data[0]);
      Object.keys(this).forEach(key => {
        if (key[0] === "_") {
          console.log(`Freezing "${key}"`);
          Object.defineProperty(this,key,{ enumerable: false });
        }
      });
    }
  };
}

@fixEnumerables
class User {
  public name: string;
  public email: string;
  private _active: boolean;
  constructor(data: any) {}
}

const x = new User({ name: "Sam",email: "email@example.com",_active: false });
console.log(JSON.stringify(x));

// Output
// Freezing "_active"
// {"name":"Sam","email": "email@example.com"}

Blitz

本文链接:https://www.f2er.com/3164556.html

大家都在问