问题描述
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