TypeScript扩展全局Blob类型后属性访问、赋值报错如何解决?
报错原因与解决方案
报错原因
- 第一处
Property 'url' does not exist on type 'Blob'报错:你的全局类型扩展仅声明了Blob的构造函数签名,没有给Blob实例新增url、name两个属性的类型声明,TypeScript无法识别原生Blob实例上存在这两个自定义属性。 - 第二处
Cannot assign to 'name' because it is a read-only property报错:原生Blob接口本身没有name属性(该属性属于继承Blob的File接口,且默认标记为只读),同时你也没有在扩展中声明name、url为可写属性,TypeScript会判定你是在修改只读属性。
你之前的
blobToFile代码能正常运行,是因为你传入的参数实际是File类型实例,File本身自带可读的name属性,和你写的全局扩展没有关系。另外你写的Blob构造函数扩展和原生Blob的构造参数定义冲突,属于无效错误声明,建议删除。
解决方案
方案1:修正全局类型扩展(适合项目中大量用到扩展Blob属性的场景)
修改你的全局声明文件,补充实例属性声明:
declare global { interface Blob { // 不添加readonly修饰符,默认即为可写属性 name?: string; url?: string; } } // 如果当前声明文件没有其他export/import,需要加下面这行将文件标记为模块,全局声明才会生效 export {}
修改后两处报错都会自动消失。
方案2:定义自定义Blob类型(更推荐,不会污染全局Blob类型)
不需要做全局扩展,单独定义扩展后的Blob类型,在使用的地方做类型标注/断言即可:
- 定义自定义类型
interface CustomBlob extends Blob { name?: string; url?: string; }
- 第一处useState修改类型标注:
const [croppedImg, setCroppedImg] = useState<CustomBlob | null>(null);
- 第二处toBlob回调中做类型断言:
return new Promise((resolve, reject) => { canvas.toBlob( (blob) => { if (!blob) { reject("Canvas is empty"); return; } // 断言为自定义类型 const customBlob = blob as CustomBlob; customBlob.name = fileName; const fileUrl = window.URL.createObjectURL(customBlob); customBlob.url = fileUrl; resolve(customBlob); }, "image/jpeg", 1 ); });
内容的提问来源于stack exchange,提问作者Yilmaz
相关产品推荐
相关产品推荐

