我试图了解是否有一种方法可以验证JSON.parse的结果是否为不同的可能类型。在我正在开发的API中,有很多来自数据库的Json字段应该使用特定的结构,所以我想检查从数据库返回的某个JsonValue是否与给定的类型一致。
我做了一些不同的尝试,这是我定义泛型函数的方式:
parseJsonField<T>(jsonValue: Prisma.JsonValue): T {
return JSON.parse(JSON.stringify(jsonValue));
}
我想有一个东西,当jsonValue没有T类型的确切属性时,它会抛出一个错误,但这不起作用。
我在用这个类测试
export class ProgramTagsDTO {
key: string;
value: string;
constructor(key: string, value: string) {
this.key = key;
this.value = value;
}
}
当我运行这个测试时:
it('should validate', () => {
const tags: Prisma.JsonValue = [
{
key: 'key1',
value: 'value1',
wrongField: 'value',
},
{
key: 'key2',
value: 'value2',
},
];
let result = null;
const expectedResult = [
new ProgramTagsDTO('key1', 'value1'),
new ProgramTagsDTO('key2', 'value2'),
];
try {
result = programmesService.parseJsonField<ProgramTagsDTO[]>(tags);
} catch (error) {
expect(error).toBeInstanceOf(Error);
}
expect(result).toEqual(expectedResult);
});
我得到:
expect(received).toEqual(expected) // deep equality
- Expected - 2
+ Received + 3
Array [
- ProgramTagsDTO {
+ Object {
"key": "key1",
"value": "value1",
+ "wrongField": "value",
},
- ProgramTagsDTO {
+ Object {
"key": "key2",
"value": "value2",
},
]
但这不是我想要的,我想让方法抛出异常。(expect.toEqual只是用来查看日志)
2条答案
按热度按时间q5iwbnjs1#
经过几天的尝试,我和一位同事想出了这个解决方案,现在看来效果不错:
添加此导入:
我们为数组和单个值做了两个方法:
plainToClass处理数组,但是我们需要有一些通用的东西,根据你解析的内容,返回明确的数组或单个对象,所以不可能有一个像T这样的带有返回签名的方法|T[]。
anhgbhbe2#
很不幸你不能。与许多语言(例如Java)一样,泛型在编译代码时被删除。在Typescript中更糟糕的是,“类型”被删除,这意味着它转换为弱类型的JavaScript。
因此,一旦在运行时,以下代码:
简化为:
因此,没有类型信息可供检查。
此外,您正在使用一个类,请注意,即使您能够检查返回值是否符合
T
的接口,它也不会是T
的 * 示例 *,而只是一个泛型对象,碰巧具有与T
示例同名的属性。必须在运行时实现检查。类似于你上面发布的解决方案,你可以概括它:
(没有测试上面的代码,只是为了给你一个给予概念)