admin管理员组

文章数量:1326123

I have a JSON object which contains a bunch of strings...

{
    id: "1",
    amount: "57,000",
    title: "I am a test"
}

How can I convert this into an interface such as:

interface MyObj {
   id: number;
   amount: number;
   title: string;
}

Would I need to map over each object property and try to convert to the necessary type or can I simply try and force cast a JSON object into a type?

For clarity, here is some additional information.

I have an array of the example objects above, the JSON so...

[
{
    id: "1",
    amount: "57,000",
    title: "I am a test"
},
{
    id: "2",
    amount: "2347,000",
    title: "I am a test as well"
}
]

All the values within this JSON object are string. Each time we use the objects in TS, we want their types to be correct. For example, the id and amount should be numbers, they can be converted before they are stored in our state.

So I would like to convert the JSON objects in the array above into a specific interface or type. Because the types do not match I cannot just use the interface, I need to do some conversions or try and cast to a type before actually aligning to the interface. This is the question, how can I map over the JSON objects in the array and convert some of the keys from string to number (possibly?).

I have a JSON object which contains a bunch of strings...

{
    id: "1",
    amount: "57,000",
    title: "I am a test"
}

How can I convert this into an interface such as:

interface MyObj {
   id: number;
   amount: number;
   title: string;
}

Would I need to map over each object property and try to convert to the necessary type or can I simply try and force cast a JSON object into a type?

For clarity, here is some additional information.

I have an array of the example objects above, the JSON so...

[
{
    id: "1",
    amount: "57,000",
    title: "I am a test"
},
{
    id: "2",
    amount: "2347,000",
    title: "I am a test as well"
}
]

All the values within this JSON object are string. Each time we use the objects in TS, we want their types to be correct. For example, the id and amount should be numbers, they can be converted before they are stored in our state.

So I would like to convert the JSON objects in the array above into a specific interface or type. Because the types do not match I cannot just use the interface, I need to do some conversions or try and cast to a type before actually aligning to the interface. This is the question, how can I map over the JSON objects in the array and convert some of the keys from string to number (possibly?).

Share Improve this question edited Apr 27, 2021 at 16:58 StuartM asked Apr 27, 2021 at 16:42 StuartMStuartM 6,82318 gold badges89 silver badges164 bronze badges 5
  • Casting won't work as expected since amount and id are actually of type string, or is that a mistake in your example? – Jacob Commented Apr 27, 2021 at 16:43
  • What do you mean? When are you trying to process these - before pile-time (generating TS source), at pile-time, after pile-time/at run-time? – VLAZ Commented Apr 27, 2021 at 16:44
  • The types are intentionally mismatched. That is partly the issue. How would I convert the JSON object with all string values, into a respectable interface. I.e. try and cast id and number to number or default it potentionally. – StuartM Commented Apr 27, 2021 at 16:52
  • Is the ma in 57,000 supposed to be a decimal separator or a thousand separator? – VLAZ Commented Apr 27, 2021 at 17:06
  • Does this answer your question? How do I cast a JSON Object to a TypeScript class? – Julian Commented Apr 27, 2021 at 23:57
Add a ment  | 

7 Answers 7

Reset to default 4

JSON.parse reviver

JSON.parse can take an optional second argument, a reviver function -

If a reviver is specified, the value puted by parsing is transformed before being returned. Specifically, the puted value and all its properties (beginning with the most nested properties and proceeding to the original value itself) are individually run through the reviver. Then it is called, with the object containing the property being processed as this, and with the property name as a string, and the property value as arguments. If the reviver function returns undefined (or returns no value, for example, if execution falls off the end of the function), the property is deleted from the object. Otherwise, the property is redefined to be the return value.

function MyObject({ id, amount, title }) {
  this.id = id
  this.amount = amount
  this.title = title
}

function reviver(key, value) {
  if (value?.id && value?.amount && value?.title)
    return new MyObject(value)
  else
    return value
}

const json =
  `[{"id":"1","amount":"57,000","title":"I am a test"},{"id":"2","amount":"13,000","title":"I am also test"},{"id":"3","amount":"1,000","title":"I am a third test"},{"id":"4","amount":"200","something":"else"},1,"foo"]`

const data =
  JSON.parse(json, reviver)

for (const value of data)
  console.log(value)

MyObject { id: '1', amount: '57,000', title: 'I am a test' }
MyObject { id: '2', amount: '13,000', title: 'I am also test' }
MyObject { id: '3', amount: '1,000', title: 'I am a third test' }
{ id: '4', amount: '200', something: 'else' }
1
foo

do it better

Above revive is a somewhat fragile function. Because of this, it would be remended that your JSON.stringify'd data contains a type field, or similar -

[ { type: "MyObject", ... }, { type: "Another", ... }, "foo", 1, ... ]

Now we can write reviver in a simple way -

function reviver(key, value) {
  switch (value?.type) {
    case "MyObject": return MyObject(value)
    case "OtherThing": return OtherThing(value)
    case "Another": return Another(value)
    default: return value                   // revive without modification
  }
}

TypeScript is a development/build-time tool only; that means casting (like using as) doesn't have any effect at runtime, like converting strings to numbers. Casting or using as is just a way of telling TypeScript to explicitly consider a value as being of a particular type. If you tried this:

interface MyObj {
   id: number;
   amount: number;
   title: string;
}

const data = {
    id: "1",
    amount: "57,000",
    title: "I am a test"
};

const ofType = data as MyObj;

...TypeScript will not pile since data is not patible with your interface given that the types don't align. Even if you forced it with:

const ofType = data as unknown as MyObj;

...id and amount are still going to be strings, and now you've forced a bug in your application.

TypeScript is there as a quality assurance tool for the soundness of your code; it brings nothing to the table for data conversion. So just like as with pure JavaScript, you'll have to do custom code if you need to convert things from one type to another. For example, if you have a parsed JSON array as posted:

const converted: Array<MyObj> = data.map(item => ({
  id: parseInt(item.id),
  amount: parseInt(item.replace(/,/g, '')),
  title: item.title
}));

What you all need is a parseInt() function.

Use it as follows:

const obj = {
    id: "1",
    amount: "57,000",
    title: "I am a test"
};

print(parseInt(obj.amount))         <-    Number and not string

If you want to confirm the type of variable, you can use typeof operator as follows:

print(typeof parseInt(obj.amount))         

Edited

I noticed that the given object is different from the interface MyObj

Therefore you can't do type assertion( can't use as). You must convert the given object to your type!

So what you need to do - if you know the given object looks like that:

const data: any = {
    id: "1",
    amount: "57,000",
    title: "I am a test"
}

You should do:

const myObj: MyObj = {
   id: parseInt(data['id']),
   amount: parseInt(data['amount'].replaceAll(',','')),
   title: data['title']
}

if you don't sure its look like the data consider to add more validation / default values

for example if data['id'] is undefined the Id will be NaN and if the data['title'] is undefined maybe you should add default value

First declare a class in which you want to convert JSON:

class LoginResponse {
  constructor(obj) {
    Object.assign(this, obj);
  }
  access_token;
  token_type;
  expires_in;
}

Now Convert your JSON to a javascript general object:

  const jsonString = '{"access_token": "123abc", "token_type": "Bearer", "expires_in": "24"}';
  var javascriptsObject = JSON.parse(jsonString);

Now convert the general javascript object into your desired class object:

  let desiredObject = new LoginResponse(javascriptsObject);
  console.log(desiredObject);

Output will be:

 LOG  {"access_token": "123abc", "expires_in": "24", "token_type": "Bearer"}

A simple cast will do.

Look here

var test = {
  name: ""
};

// umnown type will be 

console.log(test.name) // this is simple like test["name"].

// Now if you want it to a specific type then

interface Itest {
  name: string;
}

var myobj = test as Itest;
// or 

var myobj = < Itest > test;

// then the property will be a known property

console.log(myobj.name);

I think what you are trying to do is turn the JSON object into a JavaScript object by parsing the JSON object.

An example of how you could do this is below:

const json = '{"result": true, "count": 42}';
const obj = JSON.parse(json);

You could then access the new JavaScript object, obj, just like a regular object. It will contain the exact same information that was in the json object.

For more information about this method, visit:

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse https://www.w3schools./js/js_json_parse.asp

本文标签: javascriptConverting a JSON object into specific typeStack Overflow