Search code examples
reactjstypescriptecmascript-2016

TypeScript : Spread only excess properties


Using typescript in react, I have a interface for my component which has some necessary properties but I want to be able to pass extra properties and grab only those excess properties.
Please check the broken code below for expected result


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}
      />
    </>
  );
};



Solution

  • Shouldn't you rest the other properties into otherProps? You can do this while destructuring the props.

    Try this:

    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}
          />
        </>
      );
    };
    

    You can also add an alias to the destructured props to avoid conflicts.

    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}
          />
        </>
      );
    };