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
相关产品推荐
相关产品推荐

