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
andid
are actually of typestring
, 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
7 Answers
Reset to default 4JSON.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 thereviver
. 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 thereviver
function returnsundefined
(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
版权声明:本文标题:javascript - Converting a JSON object into specific type - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742191186a2430244.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论