How to use TypeScript to map a large object to a smaller interface?

冷暖自知 提交于 2020-12-05 11:44:01

问题


I have an object returned from a server that contains e.g.

{
    lorem: 1,
    ipsa: [2,3],
    dolor: { sit: 'amet', consectetur: 'adipiscing'},
    elit: [{you: 'get'}, {the: 'picture'}]
}

and a TypeScript interface of

export interface smallerInterface {
    ipsa: number[];
    elit: any[];
}

I'm saving the returned object into IndexedDb, and don't want to save any fields that are not present on the interface.

I have tried casting fullObject as smallerInterface and <smallerInterface>fullObject, but when saving this object into the IndexedDb, it is still including the fields lorem and dolor.

How can I map the full object to this smaller interface (hopefully without writing an explicit map function) or otherwise force TypeScript to ignore these fields?


回答1:


Typescript types do not have a runtime impact and so casting an object to different types will have no tangible effect on that object at runtime.

One of the goals of TypesScript:

  1. Use a consistent, fully erasable, structural type system.

emphasis added by me

If you want to modify an object you need code beyond types to perform the modification. Given the inability to convert between values and types like you are looking for (see this issue for further discussion), you will need to do something like:

export interface SmallerInterface {
    ipsa: number[];
    elit: any[];
}

export const smallerKeys = ['ipsa', 'elit'];

// Later once you have a result
const result = await makeRequest();
const reducedResult = smallerKeys.reduce((obj, key) =>
    ({ 
        ...obj, 
        [key]: result[key],
    }),
    {}
) as SmallerInterface;



回答2:


I have to break down a bigger object from API to Smaller classes. First of all I created smaller class using the same property name as the object from API.

export class SmallerClass {
    prop1: type,
    prop2: type,
    ...
   constructor(){
       // set default values to the props
   }
}

I use constructor to have an object with default values on creating an instance of the object.

let myObj = new SmallerClass();

let apiObj = `API Call`;

Then after receiving object from API, the instance of the SmallerClass can be instantiated using either of following methoods:
1. Using key in Object syntax

Object.keys(this.myObj).map((key) => {
   if (key in this.apiObj) {
      this.myObj [key] = this.apiObj[key];
   }
});

2. Using hasOwnProperty

Object.keys(this.myObj).map((key) => {
   if (this.apiObj.hasOwnProperty(key)) {
      this.myObj[key] = this.apiObj[key];
   }
});


来源:https://stackoverflow.com/questions/50492930/how-to-use-typescript-to-map-a-large-object-to-a-smaller-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!