Подтвердить что ты не робот

Angular2 передать результат json в интерфейс

Используя Angular2 и typescript, я вернул JSON из webApi, и мне нужно получить его в массив определенного типа. Я не могу понять, как использовать 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();
    }
}  

Как вы можете видеть, у меня есть переменная класса, называемая странами, которая является массивом интерфейса страны. Это работает так, как ожидалось. (Я знаю, что мне не нужен этот метод 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. Оно работает. Он создает массив с данными. Но это не массив, реализующий интерфейс страны.

Обратите внимание, что имена полей из JSON - это все строчные буквы, но свойства интерфейса начинаются с прописного и я кодированного интерфейса. В результате, когда я получил настоящий json, это не сработает. Есть ли способ "бросить" это на интерфейс, который должен вызвать ошибку и сообщить мне, что что-то не так?

Во многих примерах используйте карту в get, как показано ниже:

  getCountries() {
        var retVal;

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

Я не могу найти документацию по этому вопросу. Когда я пытаюсь, я никогда не получаю данные, но ошибок нет. Ошибка компиляции и отсутствие ошибки времени выполнения.

4b9b3361

Ответ 1

Вы можете сделать утверждение типа к интерфейсу, который вы ожидаете от объекта, созданного JSON.parse.

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

Однако это не приведет к ошибкам, если сервер отправит вам плохие объекты по двум причинам.

Во время компиляции транспилер не знает, что отправит сервер.

Во время выполнения вся информация о типе стирается, поскольку все скомпилировано JavaScript.

Ответ 2

Виктор Савкин имеет библиотеку для проверки времени выполнения типов для этой ситуации, но она не работает с интерфейсами, потому что Typescript не экспортирует информацию о времени выполнения на интерфейсы. Здесь обсуждается .

Существует два возможных решения:

  • Если вы знаете, что данные, поступающие из api, являются правильной формой, и вы просто хотите предоставить свою IDE/информацию о компиляторе об этой форме, вы можете использовать ее в соответствии с ответом toskv.
  • Если вы не уверены в api и хотите, чтобы ваше приложение выбрасывало, если данные неправильной формы, вам нужно будет выполнить свою собственную проверку. Это немного накладные расходы, но это хорошо для больших приложений.

В общем, я вижу типы Typescript как подсказки компилятора больше, чем строгая система типов - в конце концов, она должна скомпилироваться с нетипизированным языком.