例如,我有一个班级:
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);
}
答案 0 :(得分:1)
试试这个:
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);
}
答案 1 :(得分:1)
当您有类型T
和值x
并且您编写<T>x
时,您没有在运行时意义上执行转换。您正在执行类型断言。这意味着您告诉TypeScript x
的类型是T
。
在这种特殊情况下,如果response.json()
返回类型为any
的值,这对于反序列化操作不合理,那么TypeScript编译器将为<T>response.json()
接受T
{ {1}}。这是因为类型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.
}
这里最重要的是isExpected
功能。
它采用任何类型的值,根据我们的标准验证它,并声明如果它返回true,那么给定的值确实是预期类型Expected
。
预期类型是什么意思?
我们的isExpected
函数确定了这一点,并通过返回类型向TypeScript语言提供此信息,该类型表示如果函数返回true,则传递给它的值为{{1}类型}。
这称为用户定义类型保护功能,您可以在https://www.typescriptlang.org/docs/handbook/advanced-types.html阅读更多相关信息。