如何使动态类型可调用反应自定义钩子

问题描述

假设我有一个自定义钩子,它在一个数组中返回 3 个东西

export const useInput = (store: string) => {
  const [value,setValue] = React.useState(store);

  const bind = {
    value,onChange: (e: InputChangeEvent) => {
      setValue(e.target.value)
    }
  } 

  const reset = () => {
    setValue(store)
  }

  return [value,bind,reset]
}

并在组件中使用它

const SomeComponent = () => {
  const [name,bindName,resetName] = useInput('')
  const [email,bindEmail,resetEmail] = useInput('')
  const [confirmEmail,bindConfirmEmail,resetConfirmEmail] = useInput('')

  const onSubmitHandler = (e: FormSubmitEvent) => {
    e.preventDefault()
    console.log(`${name} ${email} ${confirmEmail}`)
    resetName();
  }
  return (
    <React.Fragment>
      <form onSubmit={onSubmitHandler}>
        <div className={styles.modalTitle}>
          {homeText.action}
        </div>
        <div className={styles.textInputContainer}>
          <input type="text" placeholder={homeText.plName} {...bindName}/>
          <ErrorMessage message={'sad'}/>
        </div>
        <div className={styles.textInputContainer}>
          <input type="email" placeholder={homeText.plEmail} {...bindEmail}/>
        </div>
        <div className={styles.textInputContainer}>
          <input type="email" placeholder={homeText.plConfirm} {...bindConfirmEmail}/>
        </div>
        <button>Submit</button>
      </form>
    </React.Fragment>
  )
}

现在 resetName() 或任何重置都是不可调用的,因为有 3 种类型,其中一种是有意义的,它不应该像 string 那样可调用,我该如何更改 {{1 }} 的返回类型,这样我就可以调用调用内容 useInput

调用 () => void 时 ts 不想要的正是这个 resetName()

我头顶上的一个解决方案是在我执行可调用的东西之前操纵类型并将其缩小到单一类型?还有什么想法吗?

更新

那么做类型断言是个好主意吗?我现在可以通过断言 (This expression is not callable. Not all constituents of type 'string | { value: string; onChange: (e: InputChangeEvent) => void; } | (() => void)' are callable. Type 'string' has no call signatures.) as 使其工作。

(() => void)

解决方法

您在这里的主要问题是 useInput 的返回类型是一个项目数组,其类型是您在 return [value,bind,reset] 中返回的 3 个值的交集,而不是您需要的元组.

您可以使用 as const 要求打字稿将数组值视为不可变的元组,这会将 useInput 的返回类型更改为元组:

return [value,reset] as const

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...