【问题标题】:Typescript complaining when calling a method from React useState initialized with an empty object从使用空对象初始化的 React useState 调用方法时打字稿抱怨
【发布时间】:2021-10-07 11:56:30
【问题描述】:

在主 App 组件中,我有一个事件处理程序,它将 onSubmit 和 onClose 回调传递给 onOpenDialog 函数

App.ts

const App = () => {
  const { onOpenDialog, onCloseDialog } = useDialog()
  
  const onOpenModal = () => {
    // Open the Dialog and pass callbacks
    onOpenDialog({
      onSubmit: (data: any) => {
        // ... CRUD operation
        onCloseDialog()
      },
      onCancel: onCloseDialog
    })

  return <button onClick={onOpenModal}>Open</button>
}

onOpenDialog 函数来自 useDialog 钩子,该钩子将回调存储在 Dialog 状态。

此状态使用空对象 ({}) 进行初始化。它在模态打开时填充,并在模态关闭时重置为初始值 ({})。

useDialog.ts

const useDialog = () => {
  const [open, setOpen] = useState<boolean>(false)
  const [dialogState, setDialogState] = useState<object>({})

  const onOpenDialog = (config?: object): void => {
    setOpen(true)
    if (isObject(config) && !isEmpty(config)) {
      setDialogState(config!)
    }
  }
  
  const onCloseDialog = (): void => {
    setOpen(false)
    if (!isEmpty(dialogState)) {
      setDialogState({})
    }
  }
}

最后,我的模态表单组件有一个钩子,它导出两个处理程序(onSubmit 和 onCancel),它们将在模态表单组件中调用

useModalForm.ts

const useModalForm = () => {
  const { dialogState } = useDialog()

  const onSubmit = (data: any) => {
    dialogState.onSubmit(data) // Property 'onSubmit' does not exist on type 'object'
  }

  return {
    onSubmit: onSubmit,
    onCancel: dialogState.onCancel,
  }
}

我不能打电话给dialogState.onSubmit(data),因为打字稿抱怨 onSubmit 在类型“对象”中不存在(我理解)

我如何 - 在 Typescript 中 - 将初始/关闭状态设置为 {} 并使用我在模式打开时传递的任何回调或数据填充它。

我尝试使用预期状态签名的接口键入 useState,但是当我关闭模式时,我无法将 dialogConfig 重置为 {} 而没有 Typescript 抱怨。

【问题讨论】:

  • 你可以使用像 Record 这样的东西作为类型,而不是对象?

标签: reactjs typescript use-state


【解决方案1】:

我遇到了同样的问题并尝试了相同的解决方案。 这是我在React+TypeScript Cheatsheets 中找到的:

方法一

为预期状态创建一个类型,然后“显式声明该类型,并使用联合类型”。

type IDialogState = { /* Describe the shape of your state */ };

const [dialogState, setDialogState] = React.useState<IDialogState | null>(null);

方法2

“如果状态在设置后不久就被初始化并且总是在之后有一个值,你也可以使用类型断言:”

type IDialogState = { /* Describe the shape of your state */ };

const [dialogState, setDialogState] = React.useState<IDialogState>({} as IDialogState);

“这对于 TypeScript 编译器来说暂时是‘谎言’,即 {} 的类型为 IDialogState。您应该通过设置用户状态来跟进 - 如果您不这样做,那么您的其余代码可能依赖于用户是IDialogState 类型的,这可能会导致运行时错误。”

来源:React+TypeScript Cheatsheets (修改了变量名)


相关:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 2018-10-14
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    相关资源
    最近更新 更多