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 (980 forks)batch import
TypeScripthelp wantedneeds investigation

Repository metrics

Stars
 (11,761 stars)
PR merge metrics
 (Avg merge 6d 9h) (5 merged PRs in 30d)

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