Angular2 将 json 结果转换为接口

Posted

技术标签:

【中文标题】Angular2 将 json 结果转换为接口【英文标题】:Angular2 cast a json result to an interface 【发布时间】:2016-04-03 15:35:01 【问题描述】:

使用 Angular2 和 typescript,我从 webApi 返回 JSON,我需要将它放入特定类型的数组中。我不知道如何将 json 转换为我需要的接口。

我的类型是这个界面:

export interface Country 
    Id: number;
    Name: string;

我的模拟返回这个数组:

export var COUNTRIES: Country[] = [
     "Id": 11, "Name": "US" ,
     "Id": 12, "Name": "England" ,
     "Id": 13, "Name": "Japan" 
];

这是我的代码: country.service.ts

@Injectable()
export class CountryService 
    private _http = null;

    constructor(http: Http) 
        this._http = http;
    

    getCountries() 
        return Promise.resolve(COUNTRIES);
    

然后我用这个来称呼它:

export class CountryPickerComponent 
    public countries: Country[];

    constructor(private _countryService: CountryService)  


    getCountries() 
        this._countryService.getCountries().then(data => this.setData(data));
    

    setData(data) 
        //this.countries = data;
        this.countries = JSON.parse(data);
        var q = 1;
    

    ngOnInit() 
        this.getCountries();
    
  

如您所见,我有一个名为 countries 的类变量,它是 Country 接口的数组。这按预期工作。 (我知道我不需要那个 setData 方法——它是用来调试的)

接下来,我将服务更改为返回此 json 的 wepApi 调用。

"["name":"England","id":1,"name":"France","id":2]"

我将服务中的 getCountries 方法更改为:

getCountries() 
    return new Promise(resolve=>
        this._http.get('http://localhost:63651/Api/membercountry')
            .subscribe(data => resolve(data.json()))
    );

使用 JSON.parse,我将它转换为一个数组,然后我可以在 angular2 中使用它。有用。它使用数据创建数组。但它不是实现 Country 接口的数组。

请注意,JSON 中的字段名称都是小写的,但接口属性以大写开头,我对接口进行了编码。结果,当我得到真正的 json 时,它不起作用。有没有办法将它“投射”到界面,这应该会引发错误并让我知道有什么问题?

很多例子在get中使用map如下所示:

  getCountries() 
        var retVal;

        return new Promise(resolve=>
            this._http.get('http://localhost:63651/Api/membercountry')
                .map(ref => ref.json())
                .subscribe(data => resolve(data.json()))
        );
    

我找不到这方面的文档。当我尝试它时,我永远不会得到数据,但没有错误。没有编译错误,也没有运行时错误。

【问题讨论】:

如果你使用angular 2 betamapObservable中不可用,从http.get()返回,而是subscribe直接在Observable上使用。 【参考方案1】:

您可以对 JSON.parse 创建的对象所期望的接口进行类型断言。

 this.http.get('http://localhost:4200/').subscribe((value: Response) => 
    let hero = <ServerInfo>value.json();
  );

但是,如果服务器出于 2 个原因向您发送坏对象,这不会导致任何错误。

在编译时,转译器不知道服务器将发送什么。

在运行时,所有类型信息都会被删除,因为所有内容都被编译为 javascript

【讨论】:

在运行时它是无类型的,在编译时我们不知道 api 将返回什么。这是有道理的,但它并没有真正的帮助。我想我们需要先了解 json 并相应地构建我们的对象。 @user1617407 完全正确。你不能投射到一个未知的接口。你可以投射到任何接口,但这也无济于事。【参考方案2】:

Viktor Savkin 针对这种情况有一个library to do runtime checking of types,但它不适用于接口,因为 Typescript 不会在接口上导出运行时信息。有一个关于这个here的讨论。

有两种可能的解决方案:

如果您知道来自 api 的数据是正确的形状,并且您只是想向您的 IDE/编译器提供有关此形状的信息,您可以按照 toskv 的回答进行转换。 如果您不确定 api 并希望您的应用程序在数据形状错误时抛出异常,您将不得不实施自己的检查。这有点开销,但对于大型应用程序来说非常值得。

一般来说,我认为 Typescript 的类型不仅仅是一个严格的类型系统,而是编译器提示 - 毕竟它必须编译为无类型语言。

【讨论】:

以上是关于Angular2 将 json 结果转换为接口的主要内容,如果未能解决你的问题,请参考以下文章

Angular2:将 XML 转换为 JSON

将数据库中查询的结果转换为json, 然后调用接口的方式返回json

Angular 2 - 将 JSON 解析为具有计算属性的类

将 JSON 接口转换为数组

将 Angular 2 签名板 JSON 转换为 jQuery.signaturePad JSON

如何将 json 转换为 typescript 接口?