Typescript调用React useState初始为空对象的状态属性报错如何解决
解决方案
报错的核心原因是object属于无具体属性定义的宽泛类型,TS无法推断其包含onSubmit等属性;如果直接定义必填属性的接口,空对象{}无法满足必填属性约束,所以重置状态时会触发二次报错。以下是两种可直接落地的实现方案:
方案1:全可选属性接口(适合弹窗配置字段固定的场景)
把所有可能传入弹窗的配置属性全部设为可选,空对象天然满足类型要求:
// 定义弹窗状态接口,所有属性均为可选 interface DialogState { onSubmit?: (...args: any[]) => void onCancel?: () => void // 其他自定义字段统一在此声明,全部设为可选 data?: Record<string, any> title?: string } // 初始化时用该接口,空对象符合类型要求 const [dialogState, setDialogState] = useState<DialogState>({}) // 打开弹窗方法 const onOpenDialog = (config: DialogState) => { setDialogState(config) } // 关闭弹窗重置为空,不会触发类型报错 const onCloseDialog = () => { setDialogState({}) } // 调用属性前用可选链触发自动类型收窄,TS不会报错 dialogState.onSubmit?.(formValue)
方案2:泛型+联合类型(支持任意自定义配置的通用场景)
如果需要不同弹窗传入完全不同的配置字段,不固定属性结构,可以用联合类型区分关闭/打开状态,搭配泛型做动态类型适配:
// 联合类型定义:关闭时是空对象,打开时是泛型传入的自定义配置类型 type DialogState<T = Record<string, any>> = {} | T // 给useDialog加泛型支持,使用时可传入当前弹窗的专属配置类型 const useDialog = <T extends Record<string, any>>() => { const [dialogState, setDialogState] = useState<DialogState<T>>({}) const onOpenDialog = (config: T) => { setDialogState(config) } const onCloseDialog = () => { setDialogState({}) } // 衍生状态变量,用于后续类型收窄 const isDialogOpen = Object.keys(dialogState).length > 0 return { dialogState, onOpenDialog, onCloseDialog, isDialogOpen } } // 业务侧使用时传入当前弹窗的配置类型 const { dialogState, onOpenDialog, isDialogOpen } = useDialog<{ onSubmit: (val: string) => void onCancel: () => void id: number }>() // 先判断弹窗打开状态,TS会自动把dialogState收窄为传入的配置类型,可直接访问所有属性 if (isDialogOpen) { dialogState.onSubmit('提交内容') }
内容的提问来源于stack exchange,提问作者eakl
相关产品推荐
相关产品推荐

