Json 当属性不';不匹配?
例如,我有一个类:Json 当属性不';不匹配?,json,angular,typescript,Json,Angular,Typescript,例如,我有一个类: export class SomeClass { id: number; name: string; } 我从服务器接收到的JSON看起来不像这样 [{"Id":1,"Name":"typicalname"},{"Id":2,"Name":"somename"},{"Id":3,"Name":"blablabla"},{"Id":4,"Name":"lol"},{"Id":5,"Name":"lil"},{"Id":6,"Name":"lal"}] 当属性不匹配时,如
export class SomeClass {
id: number;
name: string;
}
我从服务器接收到的JSON看起来不像这样
[{"Id":1,"Name":"typicalname"},{"Id":2,"Name":"somename"},{"Id":3,"Name":"blablabla"},{"Id":4,"Name":"lol"},{"Id":5,"Name":"lil"},{"Id":6,"Name":"lal"}]
当属性不匹配时,如何将JSON对象强制转换为typescript类?
我现在就是这样做的,但它不起作用
getSomeClass() {
return this.http.get(this.someClassUrl)
.map(response => <SomeClass[]>response.json())
.catch(this.handleError);
}
getSomeClass(){
返回this.http.get(this.someClassUrl)
.map(response=>response.json())
.接住(这个.把手错误);
}
试试这个:
getSomeClass() {
return this.http.get(this.someClassUrl)
.map(response => {
let json = response.json();
return json.map(m => {
return {
id: json.Id,
name: json.Name
}
}
})
.catch(this.handleError);
}
当您有一个类型
T
和一个值x
并且您编写了x
时,您没有执行运行时意义上的强制转换。您正在执行类型断言。这意味着您正在告诉TypeScript,x
的类型是T
在这种特殊情况下,如果response.json()
返回类型为any
的值,这对于反序列化操作来说不是不合理的,那么对于任何T
,TypeScript编译器将接受response.json()
。这是因为类型any
与所有内容兼容(技术上可分配)
但是,在这种情况下,您需要验证响应的形状,而编译器无法为您执行此操作。您需要编写一个适当的验证算法
什么是合适的将取决于您的应用程序的域,并且可能是不平凡的,但这里是一个示例。不幸的是,由于您的问题暗示了Angular 2和RxJS,因此即使是一个简单适用的答案也包含相当多的附带复杂性
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
function injected(_) {} // emit decorator metadata with flag (not pertinent)
@injected export class SomeService {
constructor(readonly http: Http) {}
getSomeValue(): Observable<Expected> {
return this.http.get(this.someResourceUrl)
.catch(handleError)
.mergeMap(response => {
const deserialized = response.json();
if (isExpected(deserialized)) {
// note the type of derserialized is Expected in this block
return Observable.of(deserialized);
}
return Observable.throw('response data did not have the expected shape');
});
}
}
export interface Expected {
id: number;
name: string;
}
function isExpected(deserialized : any): deserialized is Expected {
return typeof deserialized.id === 'number' && typeof deserialized.name === 'string';
}
function handleError(error) { // this is not really necessary, but was in the question
console.error(error); // log
return Observable.throw(error); // rethrow.
}
从'@angular/Http'导入{Http};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/mergeMap';
导入“rxjs/add/operator/catch”;
导入“rxjs/add/observable/of”;
函数注入({}//emit decorator元数据带有标志(不相关)
@注入导出类服务{
构造函数(只读http:http){}
getSomeValue():可观察{
返回this.http.get(this.someResourceUrl)
.catch(把手错误)
.mergeMap(响应=>{
const反序列化=response.json();
if(预期(反序列化)){
//注意,此块中需要反序列化的类型
可观察的返回(反序列化);
}
return Observable.throw('响应数据没有预期的形状');
});
}
}
需要导出接口{
id:编号;
名称:字符串;
}
函数isExpected(反序列化:any):应为反序列化{
返回typeof deserialized.id=='number'&&typeof deserialized.name=='string';
}
函数handleError(error){//这不是真正必要的,但存在问题
console.error(error);//日志
返回可观察的。抛出(错误);//重新抛出。
}
这里最重要的是isExpected
函数
它接受任何类型的值,根据我们的标准对其进行验证,并声明如果返回true,则给定的值确实是预期的类型,expected
属于预期类型意味着什么
我们的isExpected
函数确定了这一点,并通过其返回类型将此信息提供给TypeScript语言,该返回类型表示如果函数返回true,则传递给它的值为Expected
类型
这是一个用户定义的类型保护函数,您可以在上了解更多信息。可能重复的@HirenParekh我看到了这个问题,但我不知道该怎么办,当属性不匹配时。在这里使用类是一种非常糟糕的做法,因为任何人尝试使用它时,
instanceof
将在运行时失败(提示使用接口
而不是类
)。您需要手动编写一个函数来验证反序列化对象的形状,以便对其进行验证?如果它是服务上使用此
的方法,则如图所示传递它将失败。如果它不使用此
为什么它是该类的成员?这不符合要求。它不验证反序列化对象。@AluanHaddad实际上,OP明确提到“属性不匹配”;所以问题不在于验证,这不是我对它的解释,但无论如何,函数应该通过不返回声明为类的内容来修改OP,因为考虑到实现,这是误导性的。