getInputProps return type gives an opinion on props that it doesn't actually return
-
downshiftversion: 6.0.5 -
nodeversion: -
npm(oryarn) version:
Relevant code or config
export interface GetInputPropsOptions
extends React.HTMLProps<HTMLInputElement> {
disabled?: boolean
}
What you did:
Created a component to use as an input which wraps <input> and used Typescript to narrow down a member of its props interface that Downshift doesn't care about and then tried to apply the result of getInputProps to it.
What happened:
Typescript warns me that the types don't match.
Reproduction repository:
See line 44 here - https://codesandbox.io/s/priceless-waterfall-sj86t?file=/src/downshift/ordered-examples/00-get-root-props-example.tsx (it's a modified version of the standard Downshift examples to illustrate the issue)
Problem description:
The interface that getInputProps is declared as returning extends React.HTMLProps<HTMLInputElement> even though it returns only a tiny proportion of that interface. Because it extends React.HTMLProps<HTMLInputElement> it is giving an opinion on the shape of props that it doesn't actually care about.
Suggested solution:
Narrow down the return type of getInputProps to match the props it actually returns.
Narrow it down to what? You should be able to pass anything input related to getInputProps, and it should return those same attributes on that input element, along with the downshift defaults that are also input-related. Yes, we only return only some input attributes but also ....rest so the resulted return type is Input props. I don't see the problem here.
The problem is that the typescript interface for React.HTMLProps<HTMLInputElement> that getInputProps returns is imposing an opinion on the shape of the return value that forces the consumer to work around that shape. I assume this is because it's expected that these props will be applied to a plain HTMLInputElement rather than a custom component.
In the example I gave I created a CustomInput component that had an optional custom spellCheck prop which differs from the spellCheck prop on the React.HTMLProps<HTMLInputElement> interface. Because getInputProps returns something that extends React.HTMLProps<HTMLInputElement> typescript complains because the two interfaces don't match.
In the simple example I gave, to work around the issue I'd have to explicitly pass in spellCheck: undefined which feels unnecessary.
If the return type were changed to only contain only those props that Downshift actually cared about the typescript warning would go away.
Maybe we should also take into account to fix all return types. Related to this: https://github.com/downshift-js/downshift/pull/1246
I'd rather have a large PR to fix as many types as possible, as these PRs are breaking changes, unfortunately.
Does it make sense @MarkFalconbridge ?
Yes, that makes sense to me.
I think the type for useCombobox are more accurate. I will not update downshift anymore, so maybe consider using useCombobox.
export interface UseComboboxGetInputPropsOptions
extends GetInputPropsOptions,
GetPropsWithRefKey {}
// ...
getInputProps: (
options?: UseComboboxGetInputPropsOptions,
otherOptions?: GetPropsCommonOptions,
) => any