Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 728
StuperUser Avatar asked May 23 '18 16:05

StuperUser


1 Answers

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;
like image 167
casieber Avatar answered Oct 19 '22 06:10

casieber