Если у меня есть общий компонент ввода в форме React Hook, который можно использовать как для регистрации, так и для входа в систему, как я могу сделать IFormValues гибким, чтобы его можно было использовать для обеих форм с разными входными данными? Sign Up имеет входные данные электронной почты, пароля и подтверждения пароля, тогда как Sign In имеет только входные данные электронной почты и пароля.
interface IFormValues {
email: string;
password: string;
confirmPassword: string;
}
type InputProps = {
hookValue: Path<IFormValues>;
register: UseFormRegister<IFormValues>;
id: string;
...etc
};
const Input = ({ hookValue, id, ...etc }: InputProps) =>
<StyledInput {...register(hookValue)} id = {id} ...etc />
Будет ли это тип союза, подобный этому? (или есть способ передать правильный тип, используемый компоненту ввода?)
interface ISignIn {
email: string;
password: string;
}
interface ISignUp extends ISignIn {
confirmPassword: string;
}
type InputProps = {
hookValue: Path<ISignIn | ISignUp>;
register: UseFormRegister<ISignIn | ISignUp>;
id: string;
...etc
};
Я попытался реализовать с помощью вышеизложенного, но это приводит к приведенной ниже ошибке TypeScript для меня при вызове компонента:
<Input
register = {register} // this errors with the below output
hookValue = "email"
label = "Email"
/>
(property) register: UseFormRegister<ISignUp | ISignIn>
Type 'UseFormRegister<{ email: string; password: string; confirmPassword: string; }>' is not assignable to type 'UseFormRegister<ISignUp | ISignIn>'.
Type 'ISignUp | ISignIn' is not assignable to type '{ email: string; password: string; confirmPassword: string; }'.
Property 'confirmPassword' is missing in type 'ISignIn' but required in type '{ email: string; password: string; confirmPassword: string; }'.ts(2322)
input.component.tsx(24, 3): The expected type comes from property 'register' which is declared here on type 'IntrinsicAttributes & InputProps'
решение 1: используйте и оператор, например ISignIn и ISignUp
решение 2: typeof-type-guards
Мне удалось заставить это работать со следующим, используя расширение, которое, как я понимаю, действует как ограничение для универсального - по сути, обеспечивая его присваивание этому типу, но сохраняя его более строгое предполагаемое значение.
export type ISignIn = {
email: string;
password: string;
};
export type ISignUp = {
email: string;
password: string;
confirmPassword: string;
};
type InputProps<IFormValues extends ISignIn | ISignUp> = {
hookValue: Path<IFormValues>;
register: UseFormRegister<IFormValues>;
};
const Input = <IFormValues extends ISignIn | ISignUp>({
hookValue,
register,
}: InputProps<IFormValues>) => {