You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中img.onload赋值报错:boolean无法兼容事件处理器类型

问题描述

我在Angular应用中实现了一个校验图片文件大小和尺寸有效性的方法,预期返回true或false,但代码报错:Type 'boolean' is not assignable to type '(this: GlobalEventHandlers, ev: Event) => any',报错行是return img.onload = function () {。

原代码如下:

checkFileValidity(file: any, multiple: boolean): any {
    const reader = new FileReader();
    const img = new Image();
    img.src = window.URL.createObjectURL(file);
    reader.readAsDataURL(file);
    return img.onload = function () {
      const tableError = []
      const width = img.width;
      const height = img.height;
      console.log(img.width);
      console.log(img.height);
      if (file.size > 3000000) {
        console.log('size');
        tableError.push('size');
      }
      if (width < 1919 || height < 1079) {
        console.log('dimension');
        tableError.push('dimension');
      }
      if (tableError.length > 0 && !multiple) {
        return false;
      } else if (tableError.length > 0) {
        console.log('size+dimension');
        return false;
      }
      return true;
    }()
  }

错误原因
  1. 类型不匹配:你错误地将onload回调的执行结果(布尔值)赋值给了img.onload,但img.onload要求的是一个事件处理函数((event: Event) => void类型),而非布尔值,导致TypeScript抛出类型错误。
  2. 异步逻辑错误:图片加载是异步操作,你立刻执行回调的写法根本等不到图片加载完成,拿到的宽高始终是0,完全起不到校验作用。
  3. 冗余代码:代码中引入了FileReader但未使用其结果,属于无效代码。

解决方案

因为图片加载是异步操作,无法直接同步返回布尔值,需改为返回Promise<boolean>来异步传递校验结果。修改后的代码如下:

checkFileValidity(file: File, multiple: boolean): Promise<boolean> {
  return new Promise((resolve) => {
    const img = new Image();
    img.src = window.URL.createObjectURL(file);
    
    img.onload = () => {
      const tableError: string[] = [];
      const width = img.width;
      const height = img.height;
      
      // 校验文件大小(3MB)
      if (file.size > 3 * 1024 * 1024) {
        tableError.push('size');
      }
      // 校验尺寸(至少1919x1079)
      if (width < 1919 || height < 1079) {
        tableError.push('dimension');
      }
      
      // 根据错误数组长度返回校验结果
      resolve(tableError.length === 0);
      
      // 释放URL对象,避免内存泄漏
      window.URL.revokeObjectURL(img.src);
    };
    
    // 处理图片加载失败的情况
    img.onerror = () => {
      resolve(false);
      window.URL.revokeObjectURL(img.src);
    };
  });
}

关键修改点
  • 将返回类型改为Promise<boolean>,适配异步操作逻辑
  • 用Promise包裹图片加载流程,通过resolve传递最终校验结果
  • 增加img.onerror处理,避免图片加载失败时程序一直处于等待状态
  • 调用URL.revokeObjectURL释放临时URL资源,防止内存泄漏
  • 简化校验逻辑,直接通过错误数组长度判断结果
  • 移除了未使用的FileReader冗余代码

使用示例(Angular组件中)
// 假设selectedFile是用户选择的文件对象
this.checkFileValidity(selectedFile, false).then(isValid => {
  if (isValid) {
    console.log('图片校验通过');
    // 执行后续逻辑,比如文件上传
  } else {
    console.log('图片大小或尺寸不符合要求');
    // 提示用户错误信息
  }
});

内容的提问来源于stack exchange,提问作者l3miage-crivoid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:42:22