downshift-js/downshift

TypeScript compiler error with ref passed from getInputProps to component using a forwardRef

Open

#718 opened on Jun 18, 2019

View on GitHub
 (9 comments) (8 reactions) (0 assignees)JavaScript (11,761 stars) (980 forks)batch import
TypeScripthelp wantedneeds investigation

Description

  • downshift version: 3.2.10
  • node version: v11.15.0
  • npm (or yarn) version: 6.7.0
  • react version: 16.8.4
  • styled-components version: 4.3.1

Relevant code or config

import * as React from "react";
import { render } from "react-dom";
import styled from "styled-components";
import Downshift from "downshift";

const Input = styled.input`
  width: 200px;
`;

function App() {
  return (
    <Downshift>
      {({ getInputProps }) => (
        <div>
          <Input
            {...getInputProps({
              onKeyUp(e: React.KeyboardEvent<HTMLInputElement>) {
                // handle key up
              }
            })}
          />
        </div>
      )}
    </Downshift>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

What you did: Attempted to pass a custom getInputProps to a component which implements a forward ref (in this case, to an <input> element).

What happened: A compiler error from TypeScript:

Type '{ onKeyUp: ((e: KeyboardEvent<HTMLInputElement>) => void) & ((event: KeyboardEvent<HTMLInputElement>) => void); disabled?: boolean; accept?: string; acceptCharset?: string; action?: string; ... 354 more ...; key?: Key; }' is not assignable to type 'Pick<Pick<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "form" | "style" | "title" | "pattern" | "onChange" | "onSelect" | "children" | ... 277 more ... | "onTransitionEndCapture"> & { ...; }, "form" | ... 284 more ... | "onTransitionEndCapture"> & Partial<...>, "form" | ... 284 mo...'.
  Types of property 'ref' are incompatible.
    Type 'LegacyRef<HTMLInputElement>' is not assignable to type '((instance: HTMLInputElement) => void) | RefObject<HTMLInputElement>'.
      Type 'string' is not assignable to type '((instance: HTMLInputElement) => void) | RefObject<HTMLInputElement>'.ts(2322)

Reproduction repository: https://codesandbox.io/s/loving-diffie-njech

Problem description: Type of ref is incompatible, even though the component appears to behave correctly with the forwarded ref.

Suggested solution: Change the type definitions to (optionally?) remove the LegacyRef part.

Contributor guide