downshift
downshift copied to clipboard
getInputProps return type gives an opinion on props that it doesn't actually return
-
downshift
version: 6.0.5 -
node
version: -
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