[英]How do I cast a JSON object to a typescript class when properties doesn't match?
For example, I have a class: 例如,我有一个课:
export class SomeClass {
id: number;
name: string;
}
I receive JSON from server than looks like this 我从服务器收到的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"}]
How do I cast a JSON object to a typescript class when properties doesn't match? 属性不匹配时,如何将JSON对象转换为Typescript类? That's how I do it wright now, and it's not working.
我现在就是这样做的,而且没有用。
getSomeClass() {
return this.http.get(this.someClassUrl)
.map(response => <SomeClass[]>response.json())
.catch(this.handleError);
}
try this: 尝试这个:
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);
}
When you have a type T
and a value x
and you write <T>x
you are not performing a cast in a runtime sense. 当您具有类型
T
和值x
并编写<T>x
,就不会在运行时意义上执行强制转换。 You are performing a type assertion. 您正在执行类型声明。 What this means is that you are telling TypeScript that the type of
x
is T
. 这意味着您要告诉TypeScript
x
的类型为T
In this particular case, if response.json()
returns a value typed as any
, which is not unreasonable for a deserialization operation, then <T>response.json()
will be accepted by the TypeScript compiler for any T
. 在这种特殊情况下,如果
response.json()
返回一个类型为any
的值,这对于反序列化操作而言是不合理的,那么<T>response.json()
将被TypeScript编译器接受为任何T
This is because the type any
is compatible with (technically assignable to) everything. 这是因为
any
类型与any
内容兼容(技术上可分配给所有类型)。
However in this case you want to verify the shape of the response and the compiler cannot do this for you. 但是,在这种情况下,您需要验证响应的形状,而编译器将无法为您执行此操作。 You need to write a validation algorithm that is appropriate.
您需要编写适当的验证算法。
What is appropriate will depend on the domain of your application, and may be non-trivial, but here is an example. 适当的选择取决于您应用程序的域,并且可能很重要,但这是一个示例。 Unfortunately, since your question implies Angular 2 and RxJS, even a simple applicable answer contains a fair amount of incidental complexity.
不幸的是,由于您的问题涉及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.
}
The most significant thing here is the isExpected
function. 这里最重要的是
isExpected
函数。
It takes a value of any type, validates it based on our criteria, and states that if it returns true, then the given value was indeed of the expected type, Expected
. 它采用任何类型的值,并根据我们的标准对其进行验证,并声明如果返回true,则给定值确实为预期类型
Expected
。
What does it mean to be of the expected type? 预期类型是什么意思?
Well our isExpected
function determines that, and provides this information to the TypeScript language by way of its return type which says that if the function returns true, then the value passed to it is of type Expected
. 好吧,我们的
isExpected
函数确定了该类型,并通过其返回类型将该信息提供给TypeScript语言,该返回类型表示如果该函数返回true,则传递给它的值将为Expected
类型。
This is known as a User Defined Type Guard function and you can read more about it at https://www.typescriptlang.org/docs/handbook/advanced-types.html . 这称为“用户定义的类型防护”功能,您可以在https://www.typescriptlang.org/docs/handbook/advanced-types.html上了解更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.