How to check if object has property that can be assigned to?

Viewed 92

Is there an easy way to check if an object has a property that can be assigned to?

Currently, I'm using:

const obj = new MyClass();
if ('property' in obj) {
  obj['property'] = value;
}

But, that results in an error if MyClass is defined like:

class MyClass {
  get property() {
    return 'value';
  }
}

In which case the property does exist, but it cannot be assigned to:

TypeError: Cannot set property quickRead of [object Object] which has only a getter
    at eval (webpack-internal:///./lib/model/construct.ts:23:29)
    at Array.forEach (<anonymous>)
    at construct (webpack-internal:///./lib/model/construct.ts:16:27)
    at new Subscription (webpack-internal:///./lib/model/subscription.ts:55:65) 
    at new Message (webpack-internal:///./lib/model/message.ts:40:5)
    at Function.fromFirestore (webpack-internal:///./lib/model/message.ts:100:12)
    at Function.fromFirestoreDoc (webpack-internal:///./lib/model/message.ts:114:29)
    at eval (webpack-internal:///./lib/api/update/messages.ts:19:64)
    at Array.filter (<anonymous>)
    at updateMessages (webpack-internal:///./lib/api/update/messages.ts:16:26)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async Promise.all (index 0)
    at async updateAccount (webpack-internal:///./pages/api/account.ts:55:5)
    at async account (webpack-internal:///./pages/api/account.ts:88:7)
    at async apiResolver (/home/ubuntu/repos/hammock/node_modules/next/dist/next-server/server/api-utils.js:8:1)

Is there a way that I can use the in keyword to check that a property can be assigned to?

2 Answers

Use getOwnPropertyDescriptor:

Example from the docs (note the writable property in the output):

const object1 = {
  property1: 42
};

const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'property1');


//For class objects, we need to check for the objects prototype. If there is multilevel inheritance, then you will have to check prototypes one by one
const descriptor2= Object.getOwnPropertyDescriptor(Object.getPrototypeOf(object2), 'property1');


console.log(descriptor1);

descriptor1 will have a lot of keys, some more relevant in your case such as getter and setter.

You are able to check exist of a property in an object by hasOwnProperty , for example :

cons myObject = {
    propertyA: "property"
};

if (myObject.hasOwnProperty("propertyA")){
    //do something
};
Related