接口(interface):
export interface User {
id: number;
name: string;
foo: string;
bar: string;
}
如何检查从后端返回的对象是否正确实现了用户界面?
最佳答案
没有通用的方法可以做到这一点。一般的想法是检查对象是否具有预期的属性以及它们是否属于预期的类型。一般来说,如果服务的输出是已知的,我会选择一些关键差异来区分输出类型并只检查那些。
在没有更多信息的情况下,这种情况的方法是:
function isUser(o: any) : o is User {
const u: User = o
return typeof u.id === "number"
&& typeof u.name === "string"
&& typeof u.foo === "string"
&& typeof u.bar === "string";
}
let o : any = {};
if(isUser(o)) {
console.log(o.id); // o is User
}
检查对象是否具有与所需类型的示例对象相同的所有属性的更通用方法是:
function is<T>(o: any, sample:T, strict = true, recursive = true) : o is T {
if( o == null) return false;
let s = sample as any;
// If we have primitives we check that they are of the same type and that type is not object
if(typeof s === typeof o && typeof o != "object") return true;
//If we have an array, then each of the items in the o array must be of the same type as the item in the sample array
if(o instanceof Array){
// If the sample was not an arry then we return false;
if(!(s instanceof Array)) return false;
let oneSample = s[0];
let e: any;
for(e of o) {
if(!is(e, oneSample, strict, recursive)) return false;
}
} else {
// We check if all the properties of sample are present on o
for(let key of Object.getOwnPropertyNames(sample)) {
if(typeof o[key] !== typeof s[key]) return false;
if(recursive && typeof s[key] == "object" && !is(o[key], s[key], strict, recursive)) return false;
}
// We check that o does not have any extra prperties to sample
if(strict) {
for(let key of Object.getOwnPropertyNames(o)) {
if(s[key] == null) return false;
}
}
}
return true;
}
示例用法:
// A more complex interface
export interface User {
id: number;
name: string;
foo: string;
bar: string;
role: {
name: string;
id: number;
}
groups: Array<{
id: number,
name: string
}>;
}
// Returned from the service
let o : any = {
role : { name : "", id: 0 },
emails: ["a", "b"],
groups: [ { id: 0, name : ""} ],
bar: "", foo: "", id: 0, name: "",
};
// What properties will be checked.
const sampleUser: User = {
role : { name : "", id: 0 },
groups: [ { id: 0, name : ""} ],
emails : [""],
bar: "",
foo: "",
id: 0,
name: "",
};
if(is(o, sampleUser)){
console.log(o.id); // o is User
}
注意我没有广泛测试通用版本,所以可能会出现一些错误和未处理的特殊情况,但如果您想走这条路,这应该会给您一个良好的开端。
关于typescript - 检查对象是否正确实现接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48442746/