Вы пытаетесь передать объект, соответствующий GetLoggedInUserHeaderRequestParam
как headers
или params
как HttpClient.get
options
, но это небезопасно, и поэтому TypeScript мешает вам это сделать.
Видите, вы объявляете параметр requestHeaderParam: GetLoggedInUserHeaderRequestParam
.Это говорит о том, что requestHeaderParam
:
- должно иметь поле
uid
, которое является string
. - может иметь поле
PSID
, которое является string
.
Но это ничего не говорит о каких-либо дополнительных полях. Объект может удовлетворять интерфейсу и содержать другие поля.И некоторые из этих других полей могут не быть 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!
})
Я поставил два примера вызовов getLoggedInUser
первых компиляцийхорошо.Второго нет.Второй пример может привести к тому, что некоторые пользователи TypeScript будут думать, что если поле не определено на интерфейсе, это поле запрещено, но это не , как правило, .Когда TypeScript применяет интерфейс к литералу объекта , он отклоняет поля, не определенные в интерфейсе, но это поведение применяется только к литералам объекта .(И это может быть переопределено утверждением типа.) Первый вызов getLoggedInUser
, который я показываю выше, показывает вам, что происходит в общем случае: объект может удовлетворять интерфейсу и при этом иметь дополнительные поля.
Итакпочему это проблема?Объявление { [header: string]: string | string[] }
для headers
говорит вам, что HttpClient.get
хочет объект, ключи которого являются строками, а значения являются либо строками, либо массивами строк. Значения не могут быть любого другого типа. Как мы только что видели, нет гарантии, что requestHeaderParam
не будет иметь полей, которые нарушают это требование.У него будет поле uid
, которое является строкой, оно может иметь поле PSID
, которое, если оно есть, является строкой, но может также иметь другие поля, которые не являются строками или массивамистроки.Так что компилятор по праву выдает ошибку.Та же самая логика применима, если вы пытаетесь использовать params
.
То, что требуется для решения, зависит в основном от контекста, в котором используется ваш код.Минимальным решением было бы просто сделать утверждение типа:
this.http.get(..., { headers: requestHeaderParam as unknown as Record<string, string>})
Сначала вам нужно пройти через unknown
(или any
), потому что типы полностью несовместимы. Обратите внимание: если вы используете только утверждение типа, защита не будет предоставлена, если будет передано значение, отличное от string
или string[]
. Данные будут просто переданы на HttpClient.get
, и вы получитеполучить ошибку или неопределенное поведение.
Или вы можете сделать утверждение типа после проверки, что у объекта нет никаких дополнительных полей.
Или это может имеет больше смысла делать requestHeaderParam
объектом определенного класса, который а) устанавливает, какие поля могут быть установлены, и б) имеет метод, который возвращает простой объект JS, который соответствует тому, что требует headers
.