Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript / Typescript - get object property visibility and type

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?

like image 662
Karl Johan Vallner Avatar asked Dec 22 '18 06:12

Karl Johan Vallner


People also ask

How do you access the properties of objects in TypeScript?

To dynamically access an object's property: Use keyof typeof obj as the type of the dynamic key, e.g. type ObjectKey = keyof typeof obj; . Use bracket notation to access the object's property, e.g. obj[myVar] .

How do you define object of objects type in TypeScript?

To define an object of objects type in TypeScript, we can use index signatures with the type set to the type for the value object. const data: { [name: string]: DataModel } = { //... }; to create a data variable of type { [name: string]: DataModel } where DataModel is an object type.

How do you pass an object as a parameter in TypeScript?

Inside the function we assign the parameters to properties in the object. To do this, we have to specify the this keyword, which refers to the calling object. The variables and parameters may have the same names. Anything we pass to the constructor as an argument, will be assigned to the property of the object.


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;
    }
like image 90
Artyom Amiryan Avatar answered Sep 29 '22 12:09

Artyom Amiryan