I'm working on a refacto for a project written in typescript and using React Hooks. I have some knowledge about typescript though I'm not really an expert, more like beginner.
I'm trying to develop some code reuse for this project (this why the refacto with hooks) and I'm getting stuck about a simple error, I can find a trick of course but I want to discover why it's not working.
I have a simple form for login with 2 inputs (email and password):
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>
);
};
I want to delay the state of my inputs to a custom hook, so it's reusable.
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];
};
Sadly, as you can see on the first screenshot I get an error:
Type 'ILoginFormInputs' does not satisfy the constraint 'IInputs'.
Index signature is missing in type 'ILoginFormInputs'.
Does typescript not treat { email: string, password: string }
as [key: string]: string]
?
Thanks a lot for reading me :)