我正在为使用打字稿并使用React Hooks编写的项目制作refacto。我虽然不是专家,但更像是初学者,因此对打字稿有一些了解。
我正在尝试为该项目开发一些代码重用(这就是为什么使用钩子进行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]
吗?
非常感谢您阅读我的文章:)
答案 0 :(得分:0)
我认为这是设计使然。您可以有多个具有相同名称的接口声明,它们将合并-但您不能对类型进行声明。 (T
是不是接口的类型)。因此,TS只是试图在这里变得非常安全。
您可以尝试将ILoginFormInputs
的定义更改为更严格的type
。
type ILoginFormInputs = {
password: string;
email: string;
}