我正在为一个用打字稿编写并使用 React Hooks 的项目做一个参考资料。我对打字稿有一些了解,虽然我不是真正的专家,更像是初学者。
我正在尝试为这个项目开发一些代码重用(这就是为什么带有钩子的 refacto(,我被一个简单的错误卡住了,我当然可以找到一个技巧,但我想发现为什么它不起作用。
我有一个简单的登录表单,有 2 个输入(电子邮件和密码(:
登录表单
import React from 'react';
import { SmartInput, RoundButton } from '@/components';
import { useMultipleInputs } from '@/hooks';
interface ILoginFormProps {
onLogin: (email: string, password: string) => Promise<void>;
errorMsg?: string;
}
interface ILoginFormInputs {
password: string;
email: string;
}
export const LoginForm = ({
onLogin,
errorMsg,
}: ILoginFormProps): JSX.Element => {
const [inputs, setInputs] = useMultipleInputs<ILoginFormInputs>(); // line where the error occur
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
const { email, password } = inputs;
e.preventDefault();
await onLogin(email, password);
};
const displayErrorMsg = () => {
if (errorMsg) {
return (
<p className='body-text body-text--medium body-text--error auth-form__form__error-msg'>
{errorMsg}
</p>
);
}
return null;
};
return (
<div className='auth-form'>
<div className='auth-form__container'>
<div className='auth-form__container__title title title--big'>
Sign in to <br />
Esport-Hatcher
</div>
<form className='auth-form__basic' onSubmit={onSubmit}>
<SmartInput
type='email'
placeholder='Email'
name='email'
icon='mail'
value={inputs.email}
onChange={setInputs}
/>
<SmartInput
type='password'
placeholder='Password'
name='password'
icon='lock'
value={inputs.password}
onChange={setInputs}
/>
{displayErrorMsg()}
<RoundButton onClick={() => null} />
</form>
</div>
</div>
);
};
我想延迟对自定义钩子的输入状态,以便它可以重用。
使用多个输入
import React, { useState } from 'react';
interface IInputs {
[key: string]: string;
}
export const useMultipleInputs = <T extends IInputs>(): [
T,
typeof onChange
] => {
const [inputs, setInputs] = useState<T | {}>({});
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputs({
...inputs,
[e.target.name]: e.target.value,
});
};
return [inputs as T, onChange];
};
可悲的是,正如您在第一个屏幕截图中看到的那样,我收到一个错误:
Type 'ILoginFormInputs' does not satisfy the constraint 'IInputs'.
Index signature is missing in type 'ILoginFormInputs'.
打字稿不把{ email: string, password: string }
当成[key: string]: string]
吗?
非常感谢您阅读我:)
我相信这是设计使然。您可以有多个具有相同名称的接口声明,它们将合并 - 但不能对类型执行此操作。(T
是类型而不是接口(。所以TS只是想在这里非常安全。
您可以尝试将ILoginFormInputs
定义更改为更严格的type
。
type ILoginFormInputs = {
password: string;
email: string;
}