如何使用 axios 在响应中将字符串转换为数字?
How can I cast a string to number in an response using axios?
我正在使用 Axios 对 public API 执行 GET 请求。这 API return 一个数值作为字符串。我需要将此值转换为数值。我的应用程序使用 tsc 运行,所以我希望我的对象的结果是一个数值,但它不是。
Axios 响应
[
{
"name": "foo1",
"value": "8123.3000"
},
{
"name": "foo2",
"value": "5132.2003"
},
{
"name": "foo3",
"value": "622.0000"
}
]
预期输出
[
{
"name": "foo1",
"value": 8123.3
},
{
"name": "foo2",
"value": 5132.2003
},
{
"name": "foo3",
"value": 622
}
]
我的代码很简单,
interface MyObj {
myString: string;
myNumber: number;
}
(async () => {
let { data }: AxiosResponse<MyObj> = await axios.get<MyObj>("/public/data");
console.log(data);
})();
我尝试使用interface
、class
、界面Number
。没有任何效果。
I leave an example of code to try it.
如何在不手动将每个值逐个转换的情况下获得预期的输出?
当声明你的 axios 请求 returns 某种类型时;这将在编译时和语法检查时进行检查。但是它不会在运行时执行此操作。如果您知道 axios 请求返回的内容与您的界面不同,则需要先转换为该格式。您可以使用 JSON.parse
函数的第二个参数来执行此操作,如下所示:
interface Item {
name: string;
value: number;
}
let responseString = `
[
{
"name": "foo1",
"value": "8123.3000"
},
{
"name": "foo2",
"value": "5132.2003"
},
{
"name": "foo3",
"value": "622.0000"
}
]`
const items: Item[] = JSON.parse(responseString, (key, value) => {
const propertiesToCast = ["value"] // Which properties should be converted from string to number
if (propertiesToCast.includes(key)) {
return parseFloat(value)
}
return value
});
console.log(items)
Axios 不会更改响应中的属性类型。请确认服务器没有向您发送错误的类型。
编辑
从您的评论来看,服务器似乎将 vslue 作为字符串而不是数字发送给您。在这种情况下,我建议使用 Ajv (https://github.com/ajv-validator/ajv),这样您就可以创建一个描述响应外观的模式。 ajv cn 也帮你把值从字符串转成数字:
const Ajv = require('ajv')
const ajv = new Ajv({
// allow chaning the type of some values from type X to type Y. depends on the source and target type:
// https://ajv.js.org/guide/modifying-data.html#coercing-data-types
// X => Y rules: https://ajv.js.org/coercion.html
coerceTypes: true,
})
const schema = {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
value: { type: 'number' },
},
required: ['name', 'value'],
additionalProperties: false,
},
}
const data = { name: 1, value: '1.1' }
console.log(typeof data.value === 'number') // false!
const valid = ajv.validate(schema, data)
if (!valid) {
console.log(ajv.errors)
process.exit(1)
}
console.log(typeof data.value === 'number') // true!
我正在使用 Axios 对 public API 执行 GET 请求。这 API return 一个数值作为字符串。我需要将此值转换为数值。我的应用程序使用 tsc 运行,所以我希望我的对象的结果是一个数值,但它不是。
Axios 响应
[
{
"name": "foo1",
"value": "8123.3000"
},
{
"name": "foo2",
"value": "5132.2003"
},
{
"name": "foo3",
"value": "622.0000"
}
]
预期输出
[
{
"name": "foo1",
"value": 8123.3
},
{
"name": "foo2",
"value": 5132.2003
},
{
"name": "foo3",
"value": 622
}
]
我的代码很简单,
interface MyObj {
myString: string;
myNumber: number;
}
(async () => {
let { data }: AxiosResponse<MyObj> = await axios.get<MyObj>("/public/data");
console.log(data);
})();
我尝试使用interface
、class
、界面Number
。没有任何效果。
I leave an example of code to try it.
如何在不手动将每个值逐个转换的情况下获得预期的输出?
当声明你的 axios 请求 returns 某种类型时;这将在编译时和语法检查时进行检查。但是它不会在运行时执行此操作。如果您知道 axios 请求返回的内容与您的界面不同,则需要先转换为该格式。您可以使用 JSON.parse
函数的第二个参数来执行此操作,如下所示:
interface Item {
name: string;
value: number;
}
let responseString = `
[
{
"name": "foo1",
"value": "8123.3000"
},
{
"name": "foo2",
"value": "5132.2003"
},
{
"name": "foo3",
"value": "622.0000"
}
]`
const items: Item[] = JSON.parse(responseString, (key, value) => {
const propertiesToCast = ["value"] // Which properties should be converted from string to number
if (propertiesToCast.includes(key)) {
return parseFloat(value)
}
return value
});
console.log(items)
Axios 不会更改响应中的属性类型。请确认服务器没有向您发送错误的类型。
编辑
从您的评论来看,服务器似乎将 vslue 作为字符串而不是数字发送给您。在这种情况下,我建议使用 Ajv (https://github.com/ajv-validator/ajv),这样您就可以创建一个描述响应外观的模式。 ajv cn 也帮你把值从字符串转成数字:
const Ajv = require('ajv')
const ajv = new Ajv({
// allow chaning the type of some values from type X to type Y. depends on the source and target type:
// https://ajv.js.org/guide/modifying-data.html#coercing-data-types
// X => Y rules: https://ajv.js.org/coercion.html
coerceTypes: true,
})
const schema = {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
value: { type: 'number' },
},
required: ['name', 'value'],
additionalProperties: false,
},
}
const data = { name: 1, value: '1.1' }
console.log(typeof data.value === 'number') // false!
const valid = ajv.validate(schema, data)
if (!valid) {
console.log(ajv.errors)
process.exit(1)
}
console.log(typeof data.value === 'number') // true!