0

I have some json like this;

example.json

{
    "id": 1,
    "name": "John Doe",
    "age": 23,
    "country": "US",
    "language": "en",
    "created_at": 1534774253,
    "updated_at": 1534774269
}

And I have a user.ts interface like this;

user.ts

interface user {
    id: number;
    name: string;
    age: number;
    country: string
}

So, how can I cast this json to an object implemented from this interface? I tried const userObj: user = JSON.parse(exampleJson); but userObj has all the properties in json. I want to generate a user object that has just user.ts properties. For example => JSON.stringify(userObj);, the output is {"id":1,"name":"John Doe","age":23,"country":"US"}.

Anyone knows a way?

  • Possible duplicate of [How do I cast a JSON object to a typescript class](https://stackoverflow.com/questions/22875636/how-do-i-cast-a-json-object-to-a-typescript-class) – Andreas Aug 20 '18 at 14:36
  • 1
    This doesn't look like a duplicate to me: the question is about dropping properties that aren't present in the TypeScript interface. – Matt McCutchen Aug 20 '18 at 14:40
  • Where does this JSON come from? TS types imported JSON files. – Estus Flask Aug 20 '18 at 14:40
  • @estus It's coming from a remote server via REST. – nihatemreyuksel Aug 20 '18 at 14:42
  • @MattMcCutchen From the accepted answer: _"You can't simple cast a plain-old-JavaScript result ... into a prototypical JavaScript/TypeScript class instance."_ + _"..., you could just do a cast to an interface (as it's purely a compile time structure)"_ -> Parse the JSON, strip the useless properties, cast to `user` (which should be named `IUser`, imho) – Andreas Aug 20 '18 at 14:57
  • See also https://stackoverflow.com/a/50378742/3731501 . Also, depending on the case it may be unnecessary to get rid of unused props. That they don't exist for TS may be enough. – Estus Flask Aug 20 '18 at 16:44

2 Answers2

1

Typescript interface is a way to help giving intellisense (hint) to your code editor and strong typing your JSON. It doesn't have the feature to help you handle purging additional properties that you don't need. Therefore, when you do const userObj: user = JSON.parse(exampleJson), you still get properties like created_at.

One way I think you can achieve what you need is probably writing a class.

class User {
  id: number;
  name: string;
  age: number;
  country: string;

  constructor(jsonString: any) {
    const userObj = JSON.parse(jsonString);

    // this part could be shorten with for loop
    this.id = userObj.id;
    this.name = userObj.name;
    this.age = userObj.age;
    this.country = userObj.country;
  }
}

Later you can use it:

const userObj = new User(exampleJson);
Jecfish
  • 4,026
  • 1
  • 18
  • 16
  • Thanks for your answer. That seems the correct way to do it but I want to ask something. If my json has a lot of user object, should I create new User objects for all of them? – nihatemreyuksel Aug 20 '18 at 14:56
  • 1
    In that case, I assume your json is an array. You can create a user object for all of them. It's fine. Just one line That is pretty straight forward: `const userList = (JSON.parse(exampleJson)).map(x => new User(x));` – Jecfish Aug 20 '18 at 15:00
  • 1
    another way you can handle this is - if you know the list of properties to pick or omit, you can use something like lodash `pick` or `omit` to pick or omit addtional properties before assigning to your `userObj`. – Jecfish Aug 20 '18 at 15:05
0

You create a function or preferably a file called 'valueObjects' which accepts the incoming object and then returns the desired object. Here is an example from some code I have:

export const Address = ({
 Street = null,
 Street2 = null,
 City = null,
 State = null,
 ZipCode = null,
 Country = 'US',
 IsVerified = null,
 IsActive = true,
 StudentID = null,
 Description = null,
 IsPrimary = null,
 AddressID = null,
 DateCreated = null,
 DateUpdated = null
} = {}) => ({
 Street,
 Street2,
 City,
 State,
 ZipCode,
 Country,
 IsVerified,
 IsActive,
 StudentID,
 Description,
 IsPrimary,
 AddressID,
 DateCreated,
 DateUpdated
});

Then all you would need to do is Address(yourObj)

Michael
  • 4,538
  • 5
  • 31
  • 58