当前位置:   article > 正文

axios中AxiosRequestConfig类型和InternalAxiosRequestConfig类型的区别

internalaxiosrequestconfig

之前用ts写了个request类方便发请求,最近想把以前写过的ts工具函数放在一起,新起了个项目。结果出现了如下的报错:

类型“(config: RequestConfig) => RequestConfig”的参数不能赋给类型“(value: InternalAxiosRequestConfig<any>) => InternalAxiosRequestConfig<any> | Promise<InternalAxiosRequestConfig<any>>”的参数。

这个RequestConfig是我自己定义的,本质上给AxiosRequestConfig添加一个拦截器的属性,如下

  1. interface MyInterceptors {
  2. // 定义请求拦截和请求错误处理函数
  3. requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig
  4. requestInterceptorsCatch?: (err: any) => any
  5. responseInterceptors?: <T = AxiosResponse>(res: T) => T
  6. responseInterceptorsCatch?: (err: any) => any
  7. }
  8. // 这些拦截器实际上是放在config里面的,因此这个接口要和AxiosRequestConfig整合
  9. export interface RequestConfig extends AxiosRequestConfig {
  10. interceptors?: MyInterceptors
  11. }

这个错误其实是出现在request拦截器(就是那个interceptor)上的,大概意思就是拦截器里,传入和返回的参数不再是那个RequestConfig或者说是AxiosRequestConfig,而是这个新类型InternalAxiosRequestConfig

我琢磨应该是aixos版本不一样了,果然之前的版本用的是0.4几的版本,现在换成了1.4.0。

那到底AxiosRequestConfig和InternalAxiosRequestConfig这个类型有啥不同呢,我翻了一下node_modules里面axios的相关type,两者的定义如下:

AxiosRequestConfig:(因为只考察header部分,所以我把该类型的其他部分全部去掉了)

  1. export interface AxiosRequestConfig<D = any> {
  2. headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders;
  3. }

InternalAxiosRequestConfig:

  1. export interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
  2. headers: AxiosRequestHeaders;
  3. }

这里涉及到一个新的类型AxiosRequestHeaders,定义如下

export type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders;

看样子应该是对headers属性进行了修改,那问题来了关键这个修改是什么意思呢,肯定是和ts的类型相关。

首先ts是可以通过extends的方式,修改原有对象接口的字段属性的,但是这个新的字段的类型要和原先相兼容,我写了一个例子如下

  1. interface A {
  2. age?:string|number
  3. }
  4. interface C extends A{
  5. age:number
  6. }
  7. let example:C={age:19}

例子中A类型之中的age字段直接被覆盖掉了,原先的string|number变成了number,当然可能有人问:C当中的age变成boolean,可不可以覆盖呢,也就是如下例子

  1. interface A {
  2. age?:string|number
  3. }
  4. interface C extends A{
  5. age:boolean
  6. }
  7. let example:C={age:true}

答案是不可以,在这种情况下C类型会给出如下错误

  1. Interface 'C' incorrectly extends interface 'A'.
  2. Types of property 'age' are incompatible.
  3. Type 'boolean' is not assignable to type 'string | number | undefined'.(2430)

也就是C中新规制的age字段和原先的类型不兼容。

这样的话,上面那个InternalAxiosRequestConfig类型也就好理解了,就是把原先的header字段重新规制了一下

  1. {headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders}
  2. 变成如下
  3. {headers: AxiosRequestHeaders;}
  4. 我们说type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders;
  5. 进一步转变又变成
  6. {headers:RawAxiosRequestHeaders & AxiosHeaders}

那结合整篇文章就可以知道InternalAxiosRequestConfig和AxiosRequestConfig类型的不同,就是把headers字段中的MethodsHeaders类型排除了出来,至于这个类型为什么要排除出来呢,嘿嘿,我不知道,它是一个方法和header的键值对(类型可以参见下方),估计是给不同的方法单独配置headers用的,但是在我们的interceptors中,应该没什么用了,所以才剔除掉。感兴趣的可以去github上面看看有没有相关信息

  1. type MethodsHeaders = Partial<{
  2. [Key in Method as Lowercase<Key>]: AxiosHeaders;
  3. } & {common: AxiosHeaders}>;

最后自己写了个类似的例子

  1. interface X{
  2. x:boolean
  3. }
  4. interface Y{
  5. y:string
  6. }
  7. interface Z{
  8. z:number
  9. }
  10. interface AxiosRequestConfig{
  11. headers:(X&Y)|Z
  12. }
  13. interface InternalAxiosRequestConfig extends AxiosRequestConfig{
  14. headers:X&Z
  15. }
  16. let ex:InternalAxiosRequestConfig={
  17. headers:{
  18. x:true,
  19. z:19,
  20. //y:"hh" 这边就会报错啦
  21. }
  22. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/299734
推荐阅读
相关标签
  

闽ICP备14008679号