Javascript / Typescript - get object property visibility and type

Viewed 3397

My problem:

I need to differentiate between the private, public and getter (get X()) properties of a typescript class.

My Project:

I have an Angular project, that has a model design pattern. Aka. an user model would look like this

class UserModel extends BaseModel {
    private _id: number;

    get id() { return this._id; }
    set id( _id: number ) { this._id = _id; }
}

To send these models to the backend, I just JSON.stringify() them, which if the user id is set as 13, returns an object like this

{
    _id: 13
}

Now I need to modify the toJSON() function on the UserModel, so that instead of returning the private properties of the object, I will return the get X() variables only. The output should look like this.

{
    id: 13
}

I made this simple function, to retrieve all properties of an object, but this gives me the private properties and the get properties both.

abstract class BaseModel {
    public propsToObj() : {[key: string]: any} {
        let ret: any = {};

        for (var prop in this) {
            ret[prop] = this[prop];
        }

        return ret;
    }
}

and the toJSON function looks like this

class UserModel extends BaseModel {
    private _id: number;

    get id() { return this._id; }
    set id( _id: number ) { this._id = _id; }

    toJSON() {
        return this.propsToObj();
    }
}

The outcome of stringify-ing the UserModel looks like this

{
    _id: 13,
    id: 13
}

In conclusion, I need to know the visibility and type (getter or regular variable?) of properties on a class, how would I achieve this?

1 Answers

your propsToObj() is working wrong, it gets just all properties, you need to change it so it will get only getters, for example you can use this

abstract class BaseModel {
    public propsToObj() : {[key: string]: any} {
      let ret: any = {};

      for (const prop in this) {
        const descriptor = Object.getOwnPropertyDescriptor(this.constructor.prototype, prop);
        if (descriptor && typeof descriptor.get === 'function') {
            ret[prop] = this[prop];
        }
      }
        return ret;
    }
}

Object.getOwnPropertyDescriptor will get descriptor of a property and from which you can check if there is get function in descriptor, if it is then your property is getter, if not it is regular property, you can read more about descriptors here MDN(descriptors)

The last question you asked

I need to know the visibility and type of properties on a class, how would I achieve this?

As I know you can't get the visibility of a property, as for the type if you want to know data type of a property you can use typeof for it.

EXAMPLE in propsToObj() method:

public propsToObj() : {[key: string]: any} {
      let ret: any = {};

      for (const prop in this) {
        const descriptor = Object.getOwnPropertyDescriptor(this.constructor.prototype, prop);
        if (descriptor && typeof descriptor.get === 'function') {
            ret[prop] = this[prop];
            console.log(typeof ret[prop]); // just exaple how you can know type you can save it with property too if you need it
        }
      }
        return ret;
    }
Related