首先,场景:我是一个需要从一些REST API中检索数据的客户端,但是它们返回的json遵循了一个非常规的命名法(字段名称只有一个字符),我希望自动将响应Map到一个更显式的接口。
我提出了一个基于convert
函数的解决方案,该函数接受我用作目标模式的mapping
对象的原始响应。
这个解决方案甚至可以工作,但是我在尝试以通用(和正确)的方式设置类型时遇到了麻烦。目前我只是放了很多any
,但我想了解函数和Map对象是什么类型。
(操场在此)
理想情况下,我希望将convert
定义为泛型函数<T,U>
,将obj
定义为T
,返回值为U
,但我不知道如何正确地键入mapping
,其类型依赖于T
和U
interface AB {
a: string;
b: C;
}
interface C {
c: number;
}
interface XY {
x: string;
y: Z;
}
interface Z {
z: number;
}
const abc: AB = {
a: '...',
b: {
c: 123,
},
};
const ab_xy = {
a: 'x',
b: ['y', {
c: 'z'
}]
};
const convert = (obj: any, mapping: {}): any => {
const ret: any = {};
for (const [key_orig, value] of Object.entries(mapping)) {
const value_orig = obj[key_orig];
if (Array.isArray(value)) {// nested
const [key_new, submapping] = value;
ret[key_new] = convert(value_orig, submapping);
}
else {
const key_new = value as any;
ret[key_new] = value_orig;
}
}
return ret;
};
const expected_xyz: XY = {
x: '...',
y: {
z: 123,
}
};
const actual_xyz = convert(abc, ab_xy);
console.log(' abc: %o', abc);
console.log('expected_xyz: %o', expected_xyz);
console.log(' actual_xyz: %o', actual_xyz);
1条答案
按热度按时间qyswt5oh1#
Playground:https://tsplay.dev/wOlQdN