Angular2将json结果转换为接口

时间:2015-12-29 17:54:12

标签: json typescript angular

使用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方法 - 它用于调试)

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

"[{"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它不起作用。有没有办法'#cast;'这个接口,应该抛出一个错误让我知道出错了什么?

许多示例在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()))
        );
    }

我无法找到相关文档。当我尝试它时,我从来没有得到数据,但没有错误。没有编译错误,也没有运行时错误。

2 个答案:

答案 0 :(得分:15)

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

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

但是,如果服务器因为两个原因发送了坏对象,则不会导致任何错误。

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

在运行时,所有类型信息都被删除,因为所有类型信息都被编译到了 的JavaScript。

答案 1 :(得分:5)

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

有两种可能的解决方案:

  • 如果你知道来自api的数据是正确的形状,并且你只是想给你的IDE /编译器有关这个形状的信息,你可以根据toskv的答案进行投射。
  • 如果您不确定api并希望您的应用程序在数据形状错误时抛出,您将不得不实施自己的检查。这有点开销,但对于较大的应用程序来说非常值得。

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