简体   繁体   English

属性不匹配时,如何将JSON对象转换为Typescript类?

[英]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.

相关问题 如何将 JSON Object 转换为 TypeScript ZA2F2ED4F8EBC04ABBB4C21A2DZ? - How do I cast a JSON Object to a TypeScript class? 当我不知道键和属性没有名称时,如何在 C# 中解析 JSON 对象? - How do I parse a JSON object in C# when I don't know key and properties don't have names? 使用类将JSON对象强制转换为打字稿类型变量的正确方法? - Correct way to cast a JSON object into a typescript typed variable using a class? 在 Angular 中,如何将 JSON 响应映射到模型和 JSON 的属性不匹配的模型? - In Angular How do I map a JSON response to a model where the model's and JSON's properties don't match? 如何使用 JSON 对象初始化 TypeScript 对象? - How do I initialize a TypeScript Object with a JSON-Object? 在带有JSON对象的jQuery中使用.each时,如何避免未定义的属性? - When using .each in jQuery with a JSON object how do I avoid undefined properties? 如何将带有嵌套数组的 JSON 对象映射到打字稿模型中? - How do I map a JSON object with nested arrays into a typescript model? 如何在coffescript中总结JSON对象的属性? - How do I sum up properties of a JSON object in coffescript? 如何选择在运行时为JSON对象序列化的属性? - How do I choose which properties to serialize for a JSON object at runtime? 如何创建具有多个属性/属性的单个JSON对象? - How do I create a single JSON object with multiple attributes/properties?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM