Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter object properties matching interface

I have some objects implementing some interfaces, but they also have extra properties. When i come to serialize them (to save in a file), i would like to remove all thos extra properties, and keep only properties matching an interface.

Is there a way to "clean" an object regarding a given interface. I was trying with

Object.getOwnPropertyNames(myObject)

To get the full list of the object properties, and compare with the full list of the interface properties, but i cannot find a way to get the list of the interface properties

Edit : i found a way here : How can I create an object based on an interface file definition in TypeScript?

With

var object = <IMyInterface>{};

But i saw that when i use Object.getOwnPropertyNames(myObject), this is working only for defined properties, if a property is not defined, it's not in the result. Is there a method to get all usable properties, not only the defined ones?

like image 652
Lempkin Avatar asked May 06 '26 06:05

Lempkin


2 Answers

This can be implemented using the keyof operator in conjunction with Object.keys() to extract the keys of an object that match the properties defined in an interface:

interface IMyInterface {
  property1: string;
  property2: number;
}

function cleanObject<T>(obj: T, interfaceRef: T): T {
  const interfaceProperties = Object.keys(interfaceRef) as Array<keyof T>;
  const objectProperties = Object.keys(obj) as Array<keyof T>;

  objectProperties.forEach(property => {
    if (!interfaceProperties.includes(property)) {
      delete obj[property];
    }
  });

  return obj;
}

const myObject = { property1: 'value1', property2: 2, extraProperty: 'extraValue' };
const cleanedObject = cleanObject(myObject, <IMyInterface>{});

console.log(cleanedObject);
// Output: { property1: 'value1', property2: 2 }

Basically, cleanObject is a generic function that takes in an object obj and an interface reference interfaceRef.

The Object.keys() method is used to extract the keys of obj and interfaceRef and convert them into arrays. The keyof operator is used to ensure that the arrays contain only keys that match the properties of the respective object or interface.

Finally, a loop is used to compare the properties of obj with the properties defined in interfaceRef. If a property in obj is not present in interfaceRef, it is deleted from obj.

The cleaned object is then returned as the result of the function.

Hope this helps...

like image 165
ermalsh Avatar answered May 07 '26 20:05

ermalsh


Check out this code:

interface MyInterface1 {
    field1: string;
    field2: string;
}

interface MyInterface2 {
    field3: string;
    field4: string;
}

let o1 = {
    field1: "field1",
    field2: "field2",
    fieldN: "fieldN"
} as MyInterface1;

let o2 = {
    field3: "field3",
    field4: "field4",
    fieldN: "fieldN"
} as MyInterface2;

It compiles into:

var o1 = {
    field1: "field1",
    field2: "field2",
    fieldN: "fieldN"
};
var o2 = {
    field3: "field3",
    field4: "field4",
    fieldN: "fieldN"
};

(code in playground)

So you can see that in the compiled (js) code the interfaces do not exist, so you have no way of knowing (at runtime) what are the properties you need to keep.

What you can do is:

let myInterface1Keys = ["field1", "field2"];
interface MyInterface1 {
    field1: string;
    field2: string;
}

let o1 = {
    field1: "field1",
    field2: "field2",
    fieldN: "fieldN"
} as MyInterface1;

let persistableO1 = {} as MyInterface1;
Object.keys(o1).forEach(key => {
    if (myInterface1Keys.indexOf(key) >= 0) {
        persistableO1[key] = o1[key];
    }
});

(code in playground)

like image 26
Nitzan Tomer Avatar answered May 07 '26 20:05

Nitzan Tomer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!