Угловой 4/5 HttpClient: аргумент типа string не присваивается 'body'
Угловые документы говорят:
Тело ответа не возвращает все данные, которые могут вам понадобиться. Иногда серверы возвращают специальные заголовки или коды состояния для указания определенных условий, и их проверка может быть необходима. Для этого вы можете указать HttpClient, что вы хотите получить полный ответ, а не только тело с функцией наблюдения:
http
.get<MyJsonData>('/data.json', {observe: 'response'})
.subscribe(resp => {
// Here, resp is of type HttpResponse<MyJsonData>.
// You can inspect its headers:
console.log(resp.headers.get('X-Custom-Header'));
// And access the body directly, which is typed as MyJsonData as requested.
console.log(resp.body.someField);
});
Но когда я пытаюсь это сделать, я получаю ошибку времени компиляции (хотя ошибки времени выполнения, хотя и работают, как ожидалось):
ошибка TS2345: аргумент типа '{headers: HttpHeaders; observe: string; соблюдать: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | } 'не присваивается параметру типа' {headers?: HttpHeaders | { [header: string]: string | {[header: string]: строка | string[]; Строка []; }; }; наблюдайте?: "тело"; params?: Ht... '. Виды собственности "соблюдать" несовместимы. Тип 'string' не присваивается типу 'body' '.
Зачем? Я использую "@angular/http": "^5.1.0"
Вот моя версия кода:
login(credentials: Credentials): Observable<any> {
const options = {
headers: new HttpHeaders({'Content-Type': 'application/json'}),
observe: 'response'
};
return this.httpClient.post<any>('${environment.USER_SERVICE_BASE_URL}',
{'username': credentials.username, 'password': credentials.password}, options)
.map((res) => ...
Ответы
Ответ 1
Вы должны включить параметры. См. Билет github # 18586, запись alxhub
9 августа 2017 года.
Машинопись должна быть способна вывести значения наблюдения и responseType статически, чтобы выбрать правильный тип возврата для get(). Если вы передаете объект с неверно типизированными параметрами, он не может вывести правильный тип возврата.
login(credentials: Credentials): Observable<any> {
return this.httpClient.post<any>('${environment.USER_SERVICE_BASE_URL}',
{'username': credentials.username, 'password': credentials.password}, {
headers: new HttpHeaders({'Content-Type': 'application/json'}),
observe: 'response'
})
.map((res) => ...
Ответ 2
То, как я обошел это, без встроенных опций (что может привести к тому, что код не такой чистый) должен был создать интерфейс для параметров запроса. Код выглядит следующим образом:
export interface IRequestOptions {
body?: any;
headers?: HttpHeaders | { [header: string]: string | Array<string> };
observe?: any;
params?: HttpParams | { [param: string]: string | Array<string> };
reportProgress?: boolean;
responseType?: "arraybuffer" | "blob" | "json" | "text";
withCredentials?: boolean;
}
Затем это используется как таковое:
const options: IRequestOptions = {
headers: new HttpHeaders({"Content-Type": "application/json"}),
observe: "response"
};
return this.httpClient.post('${environment.USER_SERVICE_BASE_URL}',
{"username": credentials.username, "password": credentials.password}, options)
.pipe(
map((res: HttpResponse<any>) => ...
);
Изменение исходного сообщения для использования lettable
или pipeable
(независимо от текущего имени) операторов
Ответ 3
Машинопись жалуется на эту проблему
Тип 'string' не может быть назначен типу 'body'
Чтобы решить эту проблему, преобразуйте строку в тело вручную. Пример:
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
observe: 'response' as 'body'
};
return this.http.post<any>(url, data, httpOptions);