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

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类型,在使用的地方做类型标注/断言即可:

  1. 定义自定义类型
interface CustomBlob extends Blob {
  name?: string;
  url?: string;
}
  1. 第一处useState修改类型标注:
const [croppedImg, setCroppedImg] = useState<CustomBlob | null>(null);
  1. 第二处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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:36:03