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

TypeScript布尔判断下的条件返回类型不生效问题

问题分析

当前TypeScript代码在resolve(file)处报错,核心原因是事件回调为异步执行逻辑,TypeScript无法在回调内部追踪options的类型收窄。即便外部对options.multiple做了判断,回调执行时TS会默认认为options可能被修改,无法确定此时multiple的具体值,导致resolve参数类型不匹配。

解决方案

通过提前将multiple的状态捕获为常量,让TypeScript能在回调中正确识别该常量的字面量类型,完成类型收窄。修改后的代码如下:

type OpenFileDialogReturn<TMulti extends boolean> =
  TMulti extends true ? FileList | null | undefined :
  TMulti extends false ? File | null | undefined :
  never

type OpenFileDialog = {
  (options: { multiple?: false, acceptedFileTypes?: string }): Promise<OpenFileDialogReturn<false>>
  (options: { multiple: true, acceptedFileTypes?: string }): Promise<OpenFileDialogReturn<true>>
}

export const openFileDialog: OpenFileDialog = (options = { }) => {
  // 提前保存multiple状态到常量,让TS能追踪字面量类型
  const isMultiple = options.multiple === true;

  return new Promise(resolve => {
    const input = document.createElement('input')
    input.type = 'file'
    input.style.opacity = '0'

    if (options.acceptedFileTypes) input.accept = options.acceptedFileTypes
    input.multiple = isMultiple

    input.addEventListener('input', () => {
      if (isMultiple) {
        resolve(input.files)
        return
      }

      const file = input.files?.[0]
      resolve(file ?? null)
    })

    input.click()
  })
}

关键改动说明

  • 捕获isMultiple常量:将options.multiple的判断结果存入常量,TS会将其推断为true/false的字面量类型,回调内可稳定识别该类型。
  • 简化回调逻辑:用isMultiple替代对options.multiple的重复判断,合并空值处理为file ?? null,避免多余分支。
  • 明确input.multiple赋值:直接使用isMultiple赋值,减少重复判断的同时保证逻辑一致性。

内容的提问来源于stack exchange,提问作者Mosti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:12:44