输入“json"|undefined 不满足“json";在 Angular HttpClient 中 [英] Type "json" | undefined not satisfied by "json" in Angular HttpClient
问题描述
我正在仔细检查 HttpClient
的文档,重点介绍get(...)
方法.我准备了以下示例:
const headers: HttpHeaders = new HttpHeaders();const 观察:HttpObserve = null;const 参数:HttpParams = new HttpParams();const reportProgress = false;const responseType = "json";const withCredentials = true;常量选项 = {标题,观察,参数,reportProgress, responseType, withCredentials};this.http.get(网址,选项)
我收到一条错误消息,说明以下内容.
没有重载匹配这个调用.最后一次重载给出了以下错误.'{ responseType: string; 类型的参数... }'不可分配给类型为{ responseType?"的参数:json";|不明确的;... }'.属性responseType"的类型不兼容.类型 'string' 不可分配给类型 ''json'|不明确的'.
很明显报告的问题是什么.但是,我没有看到我输入的内容是如何验证所需内容的.如果我输入 undefined
作为 responseType
的值,编译器就会满意.事实上,详细的代码示例(编号 7、8 和 12 到 15)明确说明这是要使用的语法.
为什么我的 "json"
不是必需的 "json"
?
HttpClient
方法使用 字符串文字类型用于某些选项 - 而不仅仅是声明例如responseType
作为通用的string
,它们提供了它可以采用的特定值.那么为什么您的 options
对象 不 满足类型定义,因为它具有可接受的值之一?
初始声明:
const responseType = "json";
将responseType
定义为字符串文字类型"json"
;它是一个 const
,它只能有一个值.到现在为止还挺好.但是,object 声明:
const options = { responseType/* etc. */};
给 options
类型 { responseType: string }
,它拓宽属性的类型.这样做是因为对象是可变的,因此您可以更改该值.
要解决此问题,您有多种选择;无特定顺序:
内联对象创建:
this.http.get(url, { responseType });
这不会扩展类型,因为您不能为没有引用的对象分配不同的值.
明确输入中间对象:
const options: { responseType: "json"} = { ... };
使用 对对象的
const
断言:const options = { responseType } as const;//or =
{...}; 这告诉编译器你不会改变这些值并给
options
类型{ readonly responseType: "json";}
.在 string 上使用
const
断言(由 Michael D):const responseType = "json";作为常量;//or = <const>json";
这个有点奇怪,因为
responseType
的类型仍然是"json"
,和原来一样.然而,这会创建一个const
上下文",其中该类型是非扩展,因此options 的结果类型code> 是
{ responseType: "json"}
(不是上面的readonly
,但你只能给它赋值一个).
下面是示出用于<代码>选项代码>的各种选项的游乐场:docs for HttpClient
, focusing on the get(...)
method. I've prepared the following sample:
const headers: HttpHeaders = new HttpHeaders();
const observe: HttpObserve = null;
const params: HttpParams = new HttpParams();
const reportProgress = false;
const responseType = "json";
const withCredentials = true;
const options = {
headers, observe, params,
reportProgress, responseType, withCredentials
};
this.http.get(url, options)
I get an error stating the following.
No overload matches this call.
The last overload gave the following error.
Argument of type '{ responseType: string; ... }'
is not assignable to parameter of type '{ responseType?: "json" | undefined; ... }'.
Types of property 'responseType' are incompatible.
Type 'string' is not assignable to type '"json" | undefined'.
It's pretty obvious what's the reported issue. However, I don't see how what I typed is in validation towards what is required. If I type undefined
as the value for responseType
, the compiler is satisfied. In fact, the elaborated code samples (number 7, 8 and 12 through 15) explicitly state that it's the syntax to be used.
How is my "json"
not the required "json"
?
The HttpClient
methods use string literal types for some of the options - rather than just declaring e.g. responseType
as the generic string
they provide the specific values it can take. So why does your options
object not meet the type definition, given it has one of the accepted values?
The initial declaration:
const responseType = "json";
defines responseType
as the string literal type "json"
; it's a const
, it can only ever have that single value. So far, so good. However, the object declaration:
const options = { responseType /* etc. */ };
gives options
the type { responseType: string }
, it widens the type of the attribute. It does this because objects are mutable, so you could change the value.
To fix this, you have several options; in no particular order:
Inline the object creation:
this.http.get(url, { responseType });
This doesn't widen the type, because you can't assign a different value into an object you don't hold a reference to.
Explicitly type the intermediate object:
const options: { responseType: "json" } = { ... };
Use a
const
assertion on the object:const options = { responseType } as const; // or = <const>{...};
This tells the compiler you aren't going to change the values and gives
options
the type{ readonly responseType: "json" }
.Use a
const
assertion on the string (suggested by Michael D):const responseType = "json" as const; // or = <const>"json";
This one's a bit weird, because the type of
responseType
is still"json"
, as it was originally. However this creates a "const
context" in which that type is non-widening, so the resulting type ofoptions
is{ responseType: "json" }
(notreadonly
as above, but you can only assign that one value to it).
Here is a playground showing the various options for options
: TypeScript Playground.
这篇关于输入“json"|undefined 不满足“json";在 Angular HttpClient 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!