问题是关于如何使用对象类型发送标头(HTTPClient声明中提供的HttpHeaders除外)。
当使用Angular HttpClient时,我想将标头传递给Object,我不明白如何定义 [header:string]:string |类型的对象。 string []; ,请帮助我理解此对象声明。同样,我也面临着HttpParams的问题。我的代码方法如下。
getLoggedInUser(requestHeaderParam: GetLoggedInUserHeaderRequestParam): Observable<LoggedInUserResponse> {
return this.http.get<LoggedInUserResponse>(`${environment.apiBaseUrl}/auth/loggedInUser`,
{ headers: requestHeaderParam });
}
我在VS代码中收到如下错误消息
[ts]类型为'{头的参数:GetLoggedInUserHeaderRequestParam; }'不可分配给类型'{headers ?: HttpHeaders | { [标题:字符串]:字符串|串[]; };观察?参数?: H T...'。属性“标题”的类型不兼容。 类型'GetLoggedInUserHeaderRequestParam'不能分配给类型'HttpHeaders | {[header:string]:字符串|串[]; }'。 类型'GetLoggedInUserHeaderRequestParam'不可分配给类型'{[标头:字符串]:字符串|串[]; }'。 类型'GetLoggedInUserHeaderRequestParam'中缺少索引签名。
请求参数类型如下
export interface GetLoggedInUserHeaderRequestParam {
uid: string;
PSID?: string;
}
如下所示的HttpClient声明。
HttpClient.get(url: string, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: "body";
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: "arraybuffer";
withCredentials?: boolean;
}): Observable<ArrayBuffer>
请帮助!!!
注意:我的问题不是如何使用HttpHeaders,我得到了如何使用HttpHeaders,我的问题是如何如其声明类型之一所述直接使用Object { [标题:字符串]:字符串|串[]; }在HttpClient中
答案 0 :(得分:3)
问题是GetLoggedInUserHeaderRequestParam
和标头直接对象的签名
例如
export interface GetLoggedInUserHeaderRequestParam {
uid: string;
PSID?: string;
}
仅接受带有uid
和可选PSID
的wherease标头直接对象的对象
{
[header: string]: string | string[];
}
说它可以接受带有任意多个类型为string和value的键的对象作为字符串或字符串数组。
键的区别是您的界面强制Typescript接受具有确切键名的对象,而标头对象可以接受任何类型的字符串,如
{
"uid" : "1234",
"PSID" : "1223",
"name" : "test",
.....
}
您可以通过将接口定义为
来解决问题interface GetLoggedInUserHeaderRequestParam {
[name: string] : string | string[];
}
并以
调用HTTP方法let header: GetLoggedInUserHeaderRequestParam = {
"uid" : "1234",
"PSID" : "1234"
}
getLoggedInUser(header);
答案 1 :(得分:2)
应该是这样的:
headers是HTTP头。您提供的是数据
getLoggedInUser(requestHeaderParam: GetLoggedInUserHeaderRequestParam): Observable<LoggedInUserResponse> {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json');
return this.http.get<LoggedInUserResponse>(`${environment.apiBaseUrl}/auth/loggedInUser`, JSON.stringify(requestHeaderParam),
{ headers: headers });
}
对于参数:
import {HttpParams} from "@angular/common/http";
getLoggedInUser(requestHeaderParam: GetLoggedInUserHeaderRequestParam): Observable<LoggedInUserResponse> {
const params = new HttpParams()
.set('uid', requestHeaderParam.uid)
.set('PSID', requestHeaderParam.PSID);
return this.http.get<LoggedInUserResponse>(`${environment.apiBaseUrl}/auth/loggedInUser`,
{params:params});
}
答案 2 :(得分:2)
您正试图将符合GetLoggedInUserHeaderRequestParam
的对象作为headers
或params
传递给HttpClient.get
的{{1}},但这不是安全类型,那就是为什么TypeScript阻止您执行此操作。
请参见,您声明参数options
。这表示requestHeaderParam: GetLoggedInUserHeaderRequestParam
:
requestHeaderParam
的{{1}}字段。uid
的{{1}}字段。 但是它没有说明任何其他字段。一个对象可以满足该界面并包含其他字段。并且其中一些其他字段可能不是string
。这是一个例子。为了说明我在说什么,我摘录了部分代码,并删除了一些不重要的内容:
PSID
我已经给出了两个调用string
的示例,第一个可以很好地编译。第二个没有。第二个示例可能使TypeScript的一些用户认为,如果在接口上未定义字段,则不允许使用该字段,但通常情况并非如此。当TypeScript将接口应用于对象文字时,它将拒绝接口中未定义的那些字段,但是此行为仅适用于对象文字。 (并且可以使用类型断言来覆盖它。)上面显示的对string
的第一次调用向您展示了在一般情况下发生的情况:一个对象可以满足一个接口,但是具有其他字段。
那为什么会有问题呢? interface GetLoggedInUserHeaderRequestParam {
uid: string;
PSID?: string;
}
function getLoggedInUser(requestHeaderParam: GetLoggedInUserHeaderRequestParam): void {
}
const params = {
uid: "1",
rogue: getLoggedInUser, // Let's pass a function!
};
// This compiles just fine despite params having an extra field.
getLoggedInUser(params);
// This does not compile.
getLoggedInUser({
uid: "1",
rogue: getLoggedInUser, // Let's pass a function!
})
的{{1}}声明告诉您getLoggedInUser
想要一个对象,其键为字符串,其值为字符串或字符串数组。 值不能是任何其他类型。我们已经看到,不能保证getLoggedInUser
不会包含违反此要求的字段。它会有一个{ [header: string]: string | string[] }
字段,它是一个字符串,它可能有一个headers
字段,如果有的话,它是一个字符串,但是 可能还有其他字段不是字符串或字符串数组。因此,编译器正确地引发了一个错误。如果您尝试使用HttpClient.get
,则适用相同的逻辑。
所需的解决方案主要取决于使用代码的上下文。最小的解决方案是简单地执行类型断言:
requestHeaderParam
您必须首先通过uid
(或PSID
)进行转换,因为类型是完全不兼容的。 请注意,如果仅使用类型断言,那么如果传递的值不是params
或this.http.get(..., { headers: requestHeaderParam as unknown as Record<string, string>})
,则不会受到保护。数据只会传递到{{ 1}},您将收到错误或未定义的行为。
或者您可以在测试对象没有任何其他字段之后执行类型断言。
或者将unknown
设为特定类的对象 可能更有意义,其中a)强制设置可以设置的字段,b)具有返回纯JS的方法符合any
要求的对象。