首页 > 解决方案 > 使用枚举招摇值时,属性“fileType”的角度类型不兼容

问题描述

也许我遗漏了一些东西,但我在线程名称中提到了错误(或者在这个线程的末尾有更多细节)。

我正在尝试这样做:

   onAvatarChangeSubmit(): void {
    
        const fileUploadParams = {
          fileType: 'USER_AVATAR',
          body: {
            file: this.pictureBase64
          }
        };
    
        this.avatarFormFileUploadSubscription = this.fileControllerService.uploadFile$Response(fileUploadParams)
          .subscribe((response: StrictHttpResponse<FileUploadResponse>) => {
            console.log(response);
          });
    }

这很简单,我将 base64 编码的图像作为字符串检索,我传递了一种我想上传的文件(这次是它的用户头像),然后我将它发布到后端,在后端处理图像(文件经过验证,存储在文件系统并链接到数据库实体。然后返回实体的 UUID)。

我正在使用由 ng-openapi-gen https://www.npmjs.com/package/ng-openapi-genfileControllerService.uploadFile$Response生成的方法,它只加载 OpenAPI 3 swagger YAML 并生成一个薄 API 层(控制器服务、模型, ...)。

生成的方法具有以下签名:

  /**
   * This method provides access to the full `HttpResponse`, allowing access to response headers.
   * To access only the response body, use `uploadFile()` instead.
   *
   * This method sends `application/json` and handles request body of type `application/json`.
   */
  uploadFile$Response(params?: {
    fileType?: 'USER_AVATAR' | 'UNKNOWN' | 'DELIVERY_LOGO' | 'PAYMENT_LOGO' | 'ITEM_PICTURE';
    body?: { 'file'?: Blob }
  }): Observable<StrictHttpResponse<FileUploadResponse>> {

    const rb = new RequestBuilder(this.rootUrl, FileControllerService.UploadFilePath, 'post');
    if (params) {
      rb.query('fileType', params.fileType, {});
      rb.body(params.body, 'application/json');
    }

    return this.http.request(rb.build({
      responseType: 'blob',
      accept: '*/*'
    })).pipe(
      filter((r: any) => r instanceof HttpResponse),
      map((r: HttpResponse<any>) => {
        return r as StrictHttpResponse<FileUploadResponse>;
      })
    );
  }

方法是从我的招摇 API 正确生成的。有一个 fileType 请求参数在后端枚举,以决定如何处理特定类型的图像。

我假设该|符号意味着我可以传递以下 5 个字符串之一(UNKNOWN、USER_AVATAR、...)。但是当我这样做时(请参阅 onAvatarChangeSubmit 方法),在我传递 USER_AVATAR 字符串的地方,我收到一个可能来自打字稿编译的错误。

Failed to compile.

src/app/account/account-general/account-general.component.ts:78:92 - error TS2345: Argument of type '{ fileType: string; body: { file: string; }; }' is not assignable to parameter of type '{ fileType?: "USER_AVATAR" | "UNKNOWN" | "DELIVERY_LOGO" | "PAYMENT_LOGO" | "ITEM_PICTURE"; body?: { file?: Blob; }; }'.
  Types of property 'fileType' are incompatible.
    Type 'string' is not assignable to type '"USER_AVATAR" | "UNKNOWN" | "DELIVERY_LOGO" | "PAYMENT_LOGO" | "ITEM_PICTURE"'.

78     this.avatarFormFileUploadSubscription = this.fileControllerService.uploadFile$Response(fileUploadParams)

标签: javascriptangulartypescript

解决方案


正如您所提到的,它是打字稿抱怨不兼容的类型分配而且是的,|这意味着您可以使用这些类型中的任何一种,在这种情况下,这些文字类型

但是通过创建这个对象

       const fileUploadParams = {
          fileType: 'USER_AVATAR',
          body: {
            file: this.pictureBase64
          }
        };

在不定义任何类型的情况下,这些值默认被视为字符串,因为它们已经是字符串!在这种情况下,您正在尝试将字符串分配给另一个自定义类型

如何解决? 有不同的方法可以解决这个问题,例如:

  1. 将参数对象直接传递给函数调用,无需创建新对象:
        this.avatarFormFileUploadSubscription = 
          this.fileControllerService.uploadFile$Response({
            fileType: 'USER_AVATAR',
            body: {
              file: this.pictureBase64
            }
          })
          .subscribe((response: StrictHttpResponse<FileUploadResponse>) => {
            console.log(response);
          });
  1. 或者,为您创建的对象使用相同的类型:
       const fileUploadParams: {
         fileType: 'USER_AVATAR';
         body: { file: Blob }
       } = {
          fileType: 'USER_AVATAR',
          body: {
            file: this.pictureBase64
          }
        };

推荐阅读