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; }() }
错误原因
- 类型不匹配:你错误地将
onload回调的执行结果(布尔值)赋值给了img.onload,但img.onload要求的是一个事件处理函数((event: Event) => void类型),而非布尔值,导致TypeScript抛出类型错误。 - 异步逻辑错误:图片加载是异步操作,你立刻执行回调的写法根本等不到图片加载完成,拿到的宽高始终是0,完全起不到校验作用。
- 冗余代码:代码中引入了
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
相关产品推荐
相关产品推荐

