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()))
);
}
Я не могу найти документацию по этому вопросу. Когда я пытаюсь, я никогда не получаю данные, но ошибок нет. Ошибка компиляции и отсутствие ошибки времени выполнения.
Ответы
Ответ 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 как подсказки компилятора больше, чем строгая система типов - в конце концов, она должна скомпилироваться с нетипизированным языком.