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?
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] .
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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With