为带可选dispatch的useReducer添加TypeScript类型求助
为支持可选dispatch的useReducer reducer添加TypeScript类型
这个模式允许两种dispatch调用方式:不传参时切换当前布尔状态,传入布尔值时直接设置状态。但添加基础类型后,传参调用toggle(true)/toggle(false)会触发TypeScript错误,提示“Expected 0 arguments, but got 1”。
原代码(无类型)
[on, toggle] = useReducer( (prevState, next) => next == null ? !prevState : next, false )
尝试的代码(存在类型错误)
const [on, toggle] = useReducer( (prevState: boolean, next?: boolean) => (next == null ? !prevState : next), false ) const enable = () => toggle(true) // Error Expected 0 arguments, but got 1.ts(2554) const disable = () => toggle(false) // Error Expected 0 arguments, but got 1.ts const toggleSwitch = () => toggle() // ☑️ 正常
解决方案
问题出在TypeScript对useReducer的dispatch类型推导:当reducer的第二个参数标记为可选(next?: boolean)时,TypeScript默认认为dispatch不需要参数。我们需要显式指定action的类型为boolean | undefined,让TypeScript知道dispatch可以接受布尔值或不传参。
方法1:显式定义action参数类型
const [on, toggle] = useReducer( (prevState: boolean, next: boolean | undefined) => next == null ? !prevState : next, false ); const enable = () => toggle(true); // ☑️ 正常 const disable = () => toggle(false); // ☑️ 正常 const toggleSwitch = () => toggle(); // ☑️ 正常
方法2:使用泛型约束useReducer
const [on, toggle] = useReducer<(state: boolean, action?: boolean) => boolean>( (prevState, next) => next == null ? !prevState : next, false ); // 调用均正常 const enable = () => toggle(true); const disable = () => toggle(false); const toggleSwitch = () => toggle();
这两种方式都能让TypeScript正确识别dispatch的参数规则——既可以不传参切换状态,也可以传入布尔值直接设置状态。
内容的提问来源于stack exchange,提问作者Onat
相关产品推荐
相关产品推荐

