11

I'm using react-bootstrap lib and need to use an input component. I know how to type a simple input but have a problem with FormControl

class Search extends Component<Props, { searchInput: string }> {

      static defaultProps = {}

      state = {
        searchInput: ""
      }

     // This one works for input 
      searchInputSimple = (e: React.FormEvent<HTMLInputElement>): void => {
        const { getSearch } = this.props
        this.setState(
          { searchInput: e.currentTarget.value },
          (): void => getSearch(this.state.searchInput)
        )
      }

      // for FormControl. What can I use exept any?
      searchInput = (e: React.FormEvent<any>): void => {
        const { getSearch } = this.props
        this.setState(
          { searchInput: e.currentTarget.value },
          (): void => getSearch(this.state.searchInput)
        )
      }

      render() {
        const { searchInput } = this.state
        return (
          <>
            <InputGroup className="mb-3">
              <FormControl placeholder="Search" value={searchInput} onChange={this.searchInput} />
            </InputGroup>

            <input
              placeholder="Search"
              value={searchInput}
              onChange={this.searchInputSimple}
              className="form-control"
            />
          </>
        )
      }
    }

I tried to understand and look at FormControl.d.ts

import Feedback from './Feedback';

import { BsPrefixComponent } from './helpers';

interface FormControlProps {
  innerRef?: React.LegacyRef<this>;
  size?: 'sm' | 'lg';
  plaintext?: boolean;
  readOnly?: boolean;
  disabled?: boolean;
  value?: string;
  onChange?: React.FormEventHandler<this>;
  type?: string;
  id?: string;
  isValid?: boolean;
  isInvalid?: boolean;
}

declare class Form<
  As extends React.ReactType = 'input'
> extends BsPrefixComponent<As, FormControlProps> {
  static Feedback: typeof Feedback;
}

If I use just HTMLInputElement I'm getting this error

Type error: Type '(e: FormEvent) => void' is not assignable to type '(event: FormEvent & FormControlProps>>) => void'. Types of parameters 'e' and 'event' are incompatible. Type 'FormEvent & FormControlProps>>' is not assignable to type 'FormEvent'. Type 'Pick, HTMLInputElement>, "children" | "form" | "style" | "title" | "pattern" | "ref" | "key" | "defaultChecked" | ... 268 more ... | "width"> & BsPrefixProps<...> & FormControlProps' is missing the following properties from type 'HTMLInputElement': align, autocomplete, autofocus, dirName, and 245 more.

So how to do it and not to use any type? Should it be an alias HTMLInputElement and something more?

5 Answers 5

8

You're looking for a React.ChangeEvent, rather than a React.FormEvent:

searchInput = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const { value } = e.currentTarget;
    const { getSearch } = this.props;
    this.setState(state => ({
        ...state,
        searchInput: value
    }), (): void => getSearch(this.state.searchInput))
}
Sign up to request clarification or add additional context in comments.

5 Comments

I got almost the same error from FormControl onChange 'is not assignable to type '(event: FormEvent<ReplaceProps<"input", BsPrefixProps<"input"> & FormControlProps>>) => void''
OK, that's how we'd normally approach this from a standard Typescript/React point-of-view. Have you looked at the React Bootstrap documentation as your approach differs quite greatly. For example, you haven't defined the type of input as a prop: react-bootstrap.netlify.com/components/forms
I'm not sure that I understand what are you asking. I just copied this textarea example ibb.co/Fs0Fyww pls have a look and got 'incompatible' error
I'm getting the same error as @victorzadorozhnyy: TS2322 (TS) Type '(e: FormEvent<HTMLInputElement>) => void' is not assignable to type '(event: FormEvent<ReplaceProps<"input", BsPrefixProps<"input"> & FormControlProps>>) => void'.
It's pretty verbose, but changing the type of the input field to 'React.ChangeEvent<ReplaceProps<"input", BsPrefixProps<"input"> & FormControlProps>>' as per the error worked for me Hope you can add to this answer as your main point solved the trouble I was having
4

If you are using React.ChangeEvent this way

(e: React.ChangeEvent<HTMLInputElement>)

Please note that in your HTML code you should NOT call your function like this:

onChange={(e) => searchInput(e)}

Instead call it this way:

onChange={searchInput}

Comments

2

Instead of any, use FormControl & FormControlProps.

searchInput = (e: React.FormEvent<FormControl & FormControlProps>): void => {
  const { getSearch } = this.props
  this.setState(
    { searchInput: e.currentTarget.value as string},
    (): void => getSearch(this.state.searchInput)
  )
}

Taken from this comment on the issue in @types/react-bootstrap.

Comments

0

None of the other answers worked for me, but typing as React.BaseSyntheticEvent as suggested here did.

Comments

0

React bootstraps declares this type in FormControl without exporting it. It is simply made up of a union of 3 types

declare type FormControlElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;

What you need is:

event: React.ChangeEvent<
      HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
    >,

If this definition ever changes, go look up the docs and update with the types that exist.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.