将 http 选项设置为 'responseType: 'text'' 会导致使用 angular HttpClient 的 http post 请求编译失败
Setting http option as 'responseType: 'text'' causes compile failure for a http post request with angular HttpClient
尽管在 angular HttpClient 中有一个重载的 API 方法,如下所示:
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'text';
withCredentials?: boolean;
}): Observable<string>;
当我尝试使用选项 'responseType: 'text'' 执行以下 post 请求时,我收到一个编译器错误,指出 "No overload matches this call. ..."
const opts = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
};
return this.http.post<string>('url', null, opts);
注意:我明智地将 null 作为响应主体传递,因为我的 API 不接受主体。
我在这里做什么可能是错误的?
更新
根据 Michael D
的要求添加完整的错误消息
Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<string>'.
Type 'ArrayBuffer' is not assignable to type 'string'.ts(2322)
No overload matches this call.
Overload 1 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Overload 2 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Overload 3 of 15, '(url: string, body: any, options?: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Types of property 'responseType' are incompatible.
Type 'string' is not assignable to type '"json"'.ts(2769)
http.d.ts(2293, 9): 'observe' is declared here.
http.d.ts(2409, 9): 'observe' is declared here.
问题出在 responseType
属性 上。像这样将其分配为字符串不会立即起作用。
您可以将其转换为 text
类型
const opts = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text' as 'text' //<== here
};
this.http.post(....);
编辑
这仅适用于使用非通用版本的 http 调用(this.http.post(...)
但不适用于通用版本 this.http.post<string>
)
或者,您可以将选项声明为 any
,这应该会阻止编译器报错
const opts : any = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
};
this.http.post<string>(....)
虽然这是奇怪的行为。 HttpClient
中的 options
实际上不是任何类型。它是为每个重载定制的。
您必须将 options
作为一个整体传递到 http
调用中。
return this.http.post<string>('url', null, {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
});
或者按照 David 的建议将 options
类型设置为 any
。
opts['responseType']
被推断为 string
。尝试 responseType: 'text' as const
或
const opts = {
...
} as const;
感谢回复者的评论,我想我已经找出代码中的错误 here
问题是我正在尝试对 post() 方法调用使用泛型类型,它仅在 responseType 等于 'json' 时适用。看看下面 HttpClient 的 post 方法重载声明
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'text';
withCredentials?: boolean;
}): Observable<string>;
post<T>(url: string, body: any | null, options?: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<T>;
因此下面是我的问题的工作代码
apiMethod(): Observable<string> {
const options = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text' as 'text'
};
return this.http.post('url', null, options);
}
尽管在 angular HttpClient 中有一个重载的 API 方法,如下所示:
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'text';
withCredentials?: boolean;
}): Observable<string>;
当我尝试使用选项 'responseType: 'text'' 执行以下 post 请求时,我收到一个编译器错误,指出 "No overload matches this call. ..."
const opts = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
};
return this.http.post<string>('url', null, opts);
注意:我明智地将 null 作为响应主体传递,因为我的 API 不接受主体。 我在这里做什么可能是错误的?
更新 根据 Michael D
的要求添加完整的错误消息Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<string>'.
Type 'ArrayBuffer' is not assignable to type 'string'.ts(2322)
No overload matches this call.
Overload 1 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Overload 2 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Property 'observe' is missing in type '{ headers: HttpHeaders; responseType: string; }' but required in type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Overload 3 of 15, '(url: string, body: any, options?: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'.
Types of property 'responseType' are incompatible.
Type 'string' is not assignable to type '"json"'.ts(2769)
http.d.ts(2293, 9): 'observe' is declared here.
http.d.ts(2409, 9): 'observe' is declared here.
问题出在 responseType
属性 上。像这样将其分配为字符串不会立即起作用。
您可以将其转换为 text
类型
const opts = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text' as 'text' //<== here
};
this.http.post(....);
编辑
这仅适用于使用非通用版本的 http 调用(this.http.post(...)
但不适用于通用版本 this.http.post<string>
)
或者,您可以将选项声明为 any
,这应该会阻止编译器报错
const opts : any = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
};
this.http.post<string>(....)
虽然这是奇怪的行为。 HttpClient
中的 options
实际上不是任何类型。它是为每个重载定制的。
您必须将 options
作为一个整体传递到 http
调用中。
return this.http.post<string>('url', null, {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text'
});
或者按照 David 的建议将 options
类型设置为 any
。
opts['responseType']
被推断为 string
。尝试 responseType: 'text' as const
或
const opts = {
...
} as const;
感谢回复者的评论,我想我已经找出代码中的错误 here 问题是我正在尝试对 post() 方法调用使用泛型类型,它仅在 responseType 等于 'json' 时适用。看看下面 HttpClient 的 post 方法重载声明
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'text';
withCredentials?: boolean;
}): Observable<string>;
post<T>(url: string, body: any | null, options?: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<T>;
因此下面是我的问题的工作代码
apiMethod(): Observable<string> {
const options = {
headers: new HttpHeaders({
'Accept': 'text/html, application/xhtml+xml, */*',
'Content-Type': 'text/plain; charset=utf-8'
}),
responseType: 'text' as 'text'
};
return this.http.post('url', null, options);
}