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

如何通过TypeScript兼容方式获取上传文件的文件名

文件上传表单TS类型报错问题与解法

开发支持文件上传的表单时,两种获取上传文件名的写法在TS开发环境触发类型报错,编译生成的JS文件运行无异常,仅strict模式下的TS校验不通过。

基础页面结构

<form class="image-upload" method="post" enctype="multipart/form-data">
  <input type="file" name="upload-file">
  <input type="submit" value="Upload image">
</form>

报错场景1:基于FormData获取文件名报错

原实现代码

const form: HTMLFormElement = document.querySelector('.image-upload')!
form.addEventListener('submit', (event) => {
  event.preventDefault()
  const formattedFormData = new FormData(form)
  const data = formattedFormData.get('upload-file')!
  console.log('filename: ', data['name']); // 报错位置
})

报错信息

Element implicitly has an 'any' type because expression of type '"name"' can't be used to index type 'FormDataEntryValue'. Property 'name' does not exist on type 'FormDataEntryValue'.ts(7053)

问题根因

FormDataEntryValue是字符串与File实例的联合类型,strict模式下TS要求必须做类型窄化才能访问联合类型上的专属属性。如果直接访问.name,TS无法判断当前拿到的是带name属性的File,还是不带该属性的普通字符串,因此触发类型错误。

解决方法

  • 优先做安全类型窄化,运行时校验取值类型后再访问属性,无类型断言、无额外冗余代码:
    form.addEventListener('submit', (event) => {
      event.preventDefault()
      const formattedFormData = new FormData(form)
      const data = formattedFormData.get('upload-file')
      // 实例校验完成类型窄化
      if (data instanceof File) {
        console.log('filename: ', data.name);
      }
    })
    
  • 若确认当前表单字段一定返回File对象,可直接使用TS内置的File类型做断言,不需要自定义类型:
    form.addEventListener('submit', (event) => {
      event.preventDefault()
      const formattedFormData = new FormData(form)
      const data = formattedFormData.get('upload-file') as File
      console.log('filename: ', data.name)
    })
    

报错场景2:基于document.forms集合取值报错

原实现代码

const form: HTMLFormElement = document.querySelector('.image-upload')!
form.addEventListener('submit', (event) => {
  event.preventDefault()
  console.log('filename: ', document.forms['image-upload']['upload-file'].files[0].name) // 报错位置
})

报错信息

Element implicitly has an 'any' type because index expression is not of type 'number'.ts(7015)

问题根因

TS内置的document.forms返回值是HTMLCollectionOf<HTMLFormElement>,该类型的定义默认仅支持数字索引访问,不支持按表单名称做字符串索引取值,因此直接用字符串当key触发strict模式校验报错。

解决方法

  • 用标准DOM选择器获取元素,类型推导准确、不需要额外断言:
    form.addEventListener('submit', (event) => {
      event.preventDefault()
      // 选中文件输入控件,自动推导为HTMLInputElement类型
      const fileInput = form.querySelector<HTMLInputElement>('input[name="upload-file"]')!
      // 兼容未选文件的空值情况
      console.log('filename: ', fileInput.files?.[0]?.name)
    })
    
  • 若必须使用document.forms取值,通过内置的namedItem方法拿到表单,再做对应类型断言:
    form.addEventListener('submit', (event) => {
      event.preventDefault()
      const targetForm = document.forms.namedItem('image-upload') as HTMLFormElement
      const fileInput = targetForm.elements.namedItem('upload-file') as HTMLInputElement
      console.log('filename: ', fileInput.files?.[0]?.name)
    })
    

项目TS配置

当前项目开启了严格类型校验:

{
  "compilerOptions": {
    "strict": true
  }
}

内容的提问来源于stack exchange,提问作者Pål Stakvik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 07:06:04