箭头函数重载问题:如何让confirm分支的value类型非undefined?
修复TypeScript函数重载的类型收窄问题
问题核心在于TypeScript的控制流分析无法自动关联重载签名里的参数约束,即便判断了gesture === "confirm",编译器也没办法推导value必然是string类型。以下两种方案可解决该问题:
方案一:手动类型断言
在判断gesture为confirm后,直接将value断言为string,快速消除类型提示问题:
// 箭头函数版本 type OnCloseType = { (gesture: 'close-button' | 'cancel' | 'escape'): void; (gesture: 'confirm', value: string): void; (gesture: string, value?: string): void; }; const onClose: OnCloseType = (gesture, value) => { if (gesture === "confirm") { const confirmedValue = value as string; // 此处confirmedValue类型为string console.log(confirmedValue); } else { // 此处value可能为undefined console.log(value); } } // 普通函数重载版本 function onClose(gesture: 'close-button' | 'cancel' | 'escape'): void; function onClose(gesture: 'confirm', value: string): void; function onClose(gesture: string, value?: string): void { if (gesture === "confirm") { const confirmedValue = value as string; console.log(confirmedValue); } else { console.log(value); } }
方案二:用区分联合类型重构参数(更优雅)
将参数合并为区分联合类型,让TypeScript自动根据gesture的值收窄value的类型,从根源避免类型模糊:
// 定义区分联合类型的参数 type OnCloseParams = | { gesture: 'close-button' | 'cancel' | 'escape' } | { gesture: 'confirm'; value: string }; // 箭头函数版本 const onClose = ({ gesture, value }: OnCloseParams) => { if (gesture === "confirm") { value; // 此处value类型自动推导为string,无undefined提示 console.log(value); } else { // 此处value不存在,编译器会阻止非法访问 console.log('无传入值'); } } // 普通函数版本 function onClose(params: OnCloseParams): void { if (params.gesture === "confirm") { params.value; // 类型为string console.log(params.value); } else { console.log('无传入值'); } }
这种方式无需依赖重载,借助联合类型的区分属性(gesture)让编译器自动完成类型推导,更契合TypeScript的类型系统设计。
内容的提问来源于stack exchange,提问作者Cihad Paksoy
相关产品推荐
相关产品推荐

