Как обеспечить гибкую типизацию для пользовательского компонента ввода с помощью React Hook Form с TypeScript

Если у меня есть общий компонент ввода в форме 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'
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

решение 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>) => {

Другие вопросы по теме