typescript - 将 JSON 对象转换为接口,忽略打字稿中的大小写敏感性
问题描述
当json的某些成员与接口的成员仅区分大小写时,有什么方法可以将jsonObj“转换”为某个接口?
interface Desire {
propTest1: string,
propTest2: string
}
let jsonFromApi = {
PropTest1: "aa",
PropTest2: "bb"
}
let result = smartCast<Desire>(jsonFromApi);
console.log(results)
// I expect {
propTest1: "aa",
propTest2: "bb"
}
这是我迄今为止尝试过的:
function smartCast<T>(from: object): T{
type LOWERCASE = { [p in keyof T & string as Lowercase<`${p}`>]: T[p] }
type LOWERCASE_MAP = { [p in keyof T & string as Lowercase<`${p}`>]: p }
const lowerCase = Object.entries(from).reduce((a: any, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {}) as LOWERCASE;
console.log("lowercase ", lowerCase)
const lowerCaseMap = Object.entries(lowerCase).reduce((a: any, [key, val]) => {
a[key] = key;// how to get something like LOWERCASE_MAP[key] ?? typescript === runtime without types :(((
return a;
}, {});
return Object.entries(lowerCase).reduce((a: any, [key, val]) => {
a[lowerCaseMap[key]] = val
}, {}) as T;
}
解决方案
您想要更改在运行时从 API 获得的 JSON 对象的属性的大小写。但是对象的打字稿定义最初来自哪里?解析 JSON 通常会让您any
在设计时输入类型,除非您使用已经返回类型化对象的 API 库。
如果您没有类型定义,或者无论如何您要手动重新创建它们,只需将您的案例修改函数的返回类型设置为这种类型。您不需要为此使用打字稿的泛型:
type AnyObject = {[index: string]: unknown};
interface DesiredResultObject {
prop1: string;
prop2: number;
}
const jsonObject = {
Prop1: "answer",
Prop2: 42,
}
function toLowerCaseProps(obj: AnyObject): DesiredResultObject {
return Object.entries(obj).reduce((a, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {} as AnyObject) as unknown as DesiredResultObject;
}
const result = toLowerCaseProps(jsonObject);
如果您已经有 API 对象的类型定义并且您想要转换它们的键但不想手动创建新的类型,您可以执行以下操作:
type AnyObject = {[index: string]: unknown};
type LowerCaseProps<T extends AnyObject> = {
[K in keyof T as Lowercase<string & K>]: T[K]
};
const jsonObject = {
Prop1: "answer",
Prop2: 42
}
function toLowerCaseProps<T extends AnyObject>(obj: T): LowerCaseProps<T> {
return Object.entries(obj).reduce((a, [key, val]) => {
a[key.toLowerCase()] = val;
return a;
}, {} as AnyObject) as LowerCaseProps<T>;
}
const result = toLowerCaseProps(jsonObject);
console.log(result.prop1); // outputs "answer"
// console.log(result.Prop1); // this won't compile
console.log(result.prop2); // outputs 42
// console.log(result.Prop2); // this won't compile
推荐阅读
- c++ - 如何在 C++ 中的 .txt 文件的开头插入字符串
- angular - 在 Ionic 中使用表单会引发错误:NodeInjector: NOT_FOUND [ControlContainer]
- ios - 无法将“MyPlugin.ActivateOtpViewController”类型的值转换为“MyPlugin.ActivateOtpViewController”
- ffmpeg - 如何从 mp4 视频创建视频块 (.ts) 和 .m3u8 文件?
- amazon-dynamodb - 如果一个事务在 dynamoDB 中引发错误,则回滚所有事务
- authentication - Outlook 插件 DisplayDialogAsync iFrame 不显示页面
- flutter - Cloud Firestore/ Flutter - 按数据库排序的地图
- javascript - 使用 (Barba.js) 加载和导航新页面后脚本未加载
- java - 如何使用 com.sun.jersey.api 从响应中读取自定义 Http 标头?
- c++ - 在 C++ 中使用命名空间时出现“未命名类型”错误