如何使动态类型可调用(反应自定义挂钩)
How to make a dynamic type callable (react custom hook)
假设我有一个自定义挂钩 return数组中的 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 种类型,其中 1 种有意义,它不应该像 string
那样可调用,我如何更改 useInput
的 return 类型,这样我就可以调用可调用的东西 () => void
.
调用 resetName()
时 ts 不想要的正是这个
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)
使其工作。
const newResetName = resetName as (() => void)
newResetName()
这里的主要问题是 useInput
的 return 类型是一个项目数组,其类型是 return 在 return [value, bind, reset]
中的 3 个值的交集,而不是你需要的是一个元组。
您可以使用 as const
要求打字稿将数组值视为不可变元组,这会将 useInput
的 return 类型更改为元组:
return [value, bind, reset] as const
假设我有一个自定义挂钩 return数组中的 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 种类型,其中 1 种有意义,它不应该像 string
那样可调用,我如何更改 useInput
的 return 类型,这样我就可以调用可调用的东西 () => void
.
调用 resetName()
时 ts 不想要的正是这个
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)
使其工作。
const newResetName = resetName as (() => void)
newResetName()
这里的主要问题是 useInput
的 return 类型是一个项目数组,其类型是 return 在 return [value, bind, reset]
中的 3 个值的交集,而不是你需要的是一个元组。
您可以使用 as const
要求打字稿将数组值视为不可变元组,这会将 useInput
的 return 类型更改为元组:
return [value, bind, reset] as const