Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Input][material-ui] Input and InputBase incorrectly assumed to possibly use <textarea> when not using multiline={true} #39322

Closed
2 tasks done
NoamAnisfeld opened this issue Oct 5, 2023 · 3 comments
Labels
component: text field This is the name of the generic UI component, not the React module! typescript

Comments

@NoamAnisfeld
Copy link

NoamAnisfeld commented Oct 5, 2023

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/kv9phv?file=/src/App.tsx
Steps:

  1. Create an <Input> or <InputBase> component with no multiline prop so that it definitely renders as an <input> HTML element and not as a <textarea> HTML element
  2. Add type="file" or something similar that has specific related properties in HTMLInputElement
  3. Add an event handler like onChange
  4. In the handler, try accessing a property that only exists on HTMLInputElement such as e.target.files

Current behavior 😯

TypeScript reports an error because said property does not exit on HTMLTextAreaElement

Expected behavior 🤔

Unless using multiline={true}, the component renders as an HTMLInputElement. TypeScript should recognize it and allow accessing element properties that do not exist on HTMLTextAreaElement.

Context 🔦

I'm implementing a simple file picker and I'm forced to use an unsafe type casting or a redundant runtime check (target instanceof HTMLInputElement) to make TypeScript happy.

Your environment 🌎

npx @mui/envinfo
  System:
    OS: Windows 10 10.0.22621
  Binaries:
    Node: 18.16.1 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: Not Found
    Edge: Spartan (44.22621.2283.0), Chromium (117.0.2045.47)
  npmPackages:
    @emotion/react: ^11.11.1 => 11.11.1
    @emotion/styled: ^11.11.0 => 11.11.0
    @mui/icons-material: ^5.14.3 => 5.14.3
    @mui/material: ^5.14.3 => 5.14.3
    @mui/types: ^7.2.4 => 7.2.4
    @types/react: ^18.2.15 => 18.2.15
    react: ^18.2.0 => 18.2.0
    react-dom: ^18.2.0 => 18.2.0
    typescript: ^5.0.2 => 5.0.2
@NoamAnisfeld NoamAnisfeld added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 5, 2023
@mj12albert mj12albert changed the title Input and InputBase incorrectly assumed to possibly use <textarea> when not using multiline={true} [Input][material-ui] Input and InputBase incorrectly assumed to possibly use <textarea> when not using multiline={true} Oct 5, 2023
@mj12albert
Copy link
Member

@NoamAnisfeld You can declare the type of the event argument in the change handler, it's neither a cast nor an additional check:

-      <Input type="file" onChange={(e) => handleFile(e.target.files?.[0])} />
+      <Input
+        type="file"
+        onChange={(event: React.ChangeEvent<HTMLInputElement>) => handleFile(event.target.files?.[0])}
+      />

Here's a working sandbox: https://codesandbox.io/s/https-github-com-mui-material-ui-issues-39322-yff937?file=/src/App.tsx

@mj12albert mj12albert self-assigned this Oct 5, 2023
@mj12albert mj12albert removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 5, 2023
@mj12albert mj12albert removed their assignment Oct 5, 2023
@NoamAnisfeld
Copy link
Author

@mj12albert I see what you're saying, thanks!

However it still isn't exactly typesafe as it works the other way around too, meaning that when the <Input> element does have multiple={true} and renders a <textarea> element, it still accepts the incompatible event handler, see https://codesandbox.io/s/https-github-com-mui-material-ui-issues-39322-forked-wz9yt8?file=/src/App.tsx

@ZeeshanTamboli
Copy link
Member

@NoamAnisfeld You should define separate onChange event handlers for <input> and <textarea>. I didn't quite grasp your point, but the logs do indicate that it's functioning correctly during runtime.

@oliviertassinari oliviertassinari added the component: text field This is the name of the generic UI component, not the React module! label Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module! typescript
Projects
None yet
Development

No branches or pull requests

4 participants