输入“json"|undefined 不满足“json";在 Angular HttpClient 中 [英] Type "json" | undefined not satisfied by "json" in Angular HttpClient

查看:42
本文介绍了输入“json"|undefined 不满足“json";在 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 of options is { responseType: "json" } (not readonly 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆