TypeScript : распространяйте только лишние свойства

#reactjs #typescript #ecmascript-2016

#reactjs #машинописный текст #ecmascript-2016

Вопрос:

Используя typescript в react, у меня есть интерфейс для моего компонента, который имеет некоторые необходимые свойства, но я хочу иметь возможность передавать дополнительные свойства и захватывать только эти лишние свойства.
Пожалуйста, проверьте неработающий код ниже для получения ожидаемого результата

 
interface InputFieldProps {
  label: string;
  name: string;
  type?: string;
  placeholder?: string;
  [otherProps: string]: unknown;
}

const InputField = (props: InputFieldProps) => {
  console.log(props);

  return (
    <>
      <label htmlFor={props.name}>
        {props.label}
      </label>
      <Field
        id={props.name}
        name={props.name}
        type={props.type ? props.type : undefined}
        placeholder={props.placeholder ? props.placeholder : undefined}
        // Spread otherProps here
        {...props.otherProps}
      />
    </>
  );
};


 

Ответ №1:

Разве вы не должны использовать другие свойства otherProps ? Вы можете сделать это во время разрушения реквизита.

Попробуйте это:

 interface InputFieldProps {
  label: string;
  name: string;
  type?: string;
  placeholder?: string;
  [key: string]: unknown;
}

const InputField = ({
  name,
  label,
  type,
  placeholder,
  ...otherProps
}: InputFieldProps) => {
  return (
    <>
      <label htmlFor={name}>{label}</label>
      <Field
        id={name}
        name={name}
        type={type ? type : undefined}
        placeholder={placeholder ? placeholder : undefined}
        // Spread otherProps here
        {...otherProps}
      />
    </>
  );
};
 

Вы также можете добавить псевдоним к деструктурированным реквизитам, чтобы избежать конфликтов.

 const InputField = ({
  name: nameProp,
  label: labelProp,
  type,
  placeholder,
  ...otherProps
}: InputFieldProps) => {
  return (
    <>
      <label htmlFor={nameProp}>{labelProp}</label>
      <Field
        id={nameProp}
        name={nameProp}
        type={type ? type : undefined}
        placeholder={placeholder ? placeholder : undefined}
        // Spread otherProps here
        {...otherProps}
      />
    </>
  );
};
 

Комментарии:

1. Умный метод, это возможно, но реквизит при деструктурировании выдает label и name const, область действия которых ограничена функцией InputField и вызывает конфликт, будет ли это возможно без извлечения label и name prop ?

2. Мы извлекаем имя, метку и т.д., так что остальные свойства входят otherProps , но не все. Если они вызывают конфликт, вы всегда можете переименовать переменные, вызывающие конфликт. Вы также можете переименовать деструктурированные реквизиты, см. Обновленный ответ.