我想将API提供的对象同步到表。 该表在Sequelize中定义,并具有一个接口和一个类:
declare interface SampleInterface {
value1?: string;
value2?: string;
value3?: number;
}
class SampleClass implements SampleInterface {
value1?: string;
value2?: string;
value3?: number;
}
API的响应并不总是相同的,但可能看起来像这样:
const sampleResponse = {
value2: "..."
value3: 0
value4: "..."
}
现在,我只想创建一个可以传递给具有匹配内容的续集的新对象,例如:
const filteredResponse = {
value2: "..."
value3: 0
}
如何将对象属性键与接口或类相匹配?
谢谢!
答案 0 :(得分:1)
我认为您需要使用这样的自定义转换器来扩展TypeScript:ts-transformer-keys,以便能够获取接口的键并仅复制那些键来过滤响应。
普通TypeScript通常不允许将纯类型信息传递给运行时代码。因此,您在运行时看不到该接口,也无法知道要过滤它的字段是什么。
您可以获得类的属性名称,但必须在代码中进行设置:
Listbox
或者,您可以通过class SampleClass implements SampleInterface {
value1?: string = "";
value2?: string = "";
value3?: number = 0;
}
var a = new SampleClass();
for (var k in a) {
console.log(k); // prints value1, value2, value3
}
以这种怪异的回旋方式声明接口,因为枚举是可在运行时访问的TypeScript构造之一:
enum
答案 1 :(得分:1)
如果我正确地理解您,那么您:
具有:API产生的响应不是100%可预测的。
想要:从这个不受信任的来源创建该类的具体实例
如果我是对的,您有两种选择:
如果输入对象不是很大且不是动态对象,则可以明确地做所有事情:
const unreliableObject = fetchFromApi();
const result = new Result();
if (typeof unreliableObject.name === 'string') {
result.name = unreliableObject.name;
}
除了太太冗长之外,此代码还可以。
作为更高级的解决方案,您可以创建TransformationMapper,如下所示:
class MyClass {
name: string;
}
const expectedKeys: (keyof MyClass)[] = ['name'];
const data: any = { v: 1, name: '13212' };
const res = expectedKeys.reduce((result, fieldName) => {
const value = data[fieldName];
if (value != null) {
result[fieldName] = data[fieldName]
}
return result;
}, new MyClass());
console.log(res);
更新
有什么办法,我可以通过编程方式获取MyClass的密钥
主要思想是获得一种解析原始响应的方案。幸运的是,您已经知道了。
因此,您需要:创建所需类的实例,并从中获取键:
这可以使用:
const data: any = {};
let result = new MyClass();
result = Object.keys(result).reduce((result, fieldName) => {
const value = data[fieldName];
if (value != null) {
result[fieldName] = data[fieldName]
}
return result;
}, result)
但我也必须警告您。如果您不信任API,则不仅应解析,还应验证所解析的值。在另一种情况下,通过API提供的错误类型可能会破坏您的应用。
您可以编写自己的验证(并不难)或采用类似yup的内容
答案 2 :(得分:1)
如果您将类的字段设置为默认值并实例化该类,则可以通过编程方式获取类的字段
class SampleClass {
value1?= "";
value2?= "";
value3?= 0;
}
var keys = Object.keys(new SampleClass()) as (keyof SampleClass)[];
var ob = { value1: "asd", value2: "sdad", value4: "xxx" };
var result: SampleClass = {};
for (var k of keys) {
if (k in ob) { // remove this line if you want set missing fields to undefined
result[k] = (ob as any)[k];
}
}
console.log(result);