Sitelet https://web.archive.org/web/20210211003253/https://github.com/mui-org/material-ui/issues/24856
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

[Autocomplete] AutocompleteGetTagProps type definition could be improved #24856

Open
joemaffei opened this issue Feb 10, 2021 · 1 comment
Open

[Autocomplete] AutocompleteGetTagProps type definition could be improved #24856

joemaffei opened this issue Feb 10, 2021 · 1 comment

Comments

@joemaffei
Copy link
Contributor

@joemaffei joemaffei commented Feb 10, 2021

In this simple example, I get a Typescript error for tagProps:

type Tag = { color: string; label: string; }
type TagComponentProps = Tag & HTMLAttributes<HTMLDivElement>;
const TagComponent = styled.div<TagComponentProps>``;

function renderTags(value: Tag[], getTagProps: AutocompleteGetTagProps) {
    return value.map(({ color, label }, index) => {
        // TS2322: Type '{}' is not assignable to type 'TagComponentProps'.
        // Type '{}' is missing the following properties from type 'Tag': color, label
        const tagProps: TagComponentProps = getTagProps({ index });

        return (
            <TagComponent
                key={label}
                {...tagProps}
                color={color}
            >
                {label}
            </TagComponent>
        );
    });
}

AutocompleteGetTagProps is poorly defined in Autocomplete.d.ts:

export type AutocompleteGetTagProps = ({ index }: { index: number }) => {};

This could be solved by adding a generic to the type definition:

export type AutocompleteGetTagProps<P = {}> = ({ index }: { index: number }) => P;
function renderTags(value: Tag[], getTagProps: AutocompleteGetTagProps<TagComponentProps>) {
    // etc
    const tagProps = getTagProps({ index }); // the type is now correctly inferred
}
  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

A function that is typed as AutocompleteGetTagProps is expected to return an empty object.

Expected Behavior 🤔

AutocompleteGetTagProps should allow for correct typing of the returned object.

Steps to Reproduce 🕹

https://codesandbox.io/s/autocompletegettagprops-issue-13mlk

Steps:

  1. See issue in App.tsx
  2. See the fix in App-fixed.tsx

Context 🔦

This came up in a pull request I reviewed at work where the developer added a @ts-ignore to circumvent this issue.

Your Environment 🌎

`npx @material-ui/envinfo`
  System:
    OS: Windows 10 10.0.19042
  Binaries:
    Node: 14.12.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.5 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: Not Found
    Edge: Spartan (44.19041.423.0), Chromium (88.0.705.63)
  npmPackages:
    @emotion/styled:  10.0.27
    @material-ui/core: ^4.11.0 => 4.11.0
    @material-ui/lab: ^4.0.0-alpha.56 => 4.0.0-alpha.56
    @material-ui/styles:  4.10.0
    @material-ui/system:  4.9.14
    @material-ui/types:  5.1.0
    @material-ui/utils:  4.10.2
    @types/react:  16.9.49
    react: ^16.13.1 => 16.13.1
    react-dom: ^16.13.1 => 16.13.1
    styled-components: ^5.1.0 => 5.2.0
    typescript: ^3.9.7 => 3.9.7
tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "baseUrl": "src",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "react",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmit": true,
    "noImplicitAny": false,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "es6",
    "types": [
      "googlemaps"
    ]
  },
  "exclude": [
    "src/__*/**/*",
    "src/stories/**/*"
  ],
  "include": [
    "src"
  ]
}
@oliviertassinari
Copy link
Member

@oliviertassinari oliviertassinari commented Feb 11, 2021 •

@joemaffei Thanks for raising, the type does look wrong. I believe that this diff would solve it.

diff --git a/packages/material-ui/src/Autocomplete/Autocomplete.d.ts b/packages/material-ui/src/Autocomplete/Autocomplete.d.ts
index 6b93a57ce8..5100f085dd 100644
--- a/packages/material-ui/src/Autocomplete/Autocomplete.d.ts
+++ b/packages/material-ui/src/Autocomplete/Autocomplete.d.ts
@@ -24,7 +24,11 @@ export interface AutocompleteRenderOptionState {
   selected: boolean;
 }

-export type AutocompleteGetTagProps = ({ index }: { index: number }) => {};
+export type AutocompleteGetTagProps = ({
+  index,
+}: {
+  index: number;
+}) => React.HTMLAttributes<HTMLDivElement>;

 export interface AutocompleteRenderGroupParams {
   key: string;

Then you could have:

import Autocomplete, {
  AutocompleteGetTagProps
} from "@material-ui/core/Autocomplete";
import React from "react";
import { HTMLAttributes } from "react";

type Tag = { color: string; label: string };
type TagComponentProps = Tag & HTMLAttributes<HTMLDivElement>;
const TagComponent = ({ color, label, ...divProps }: TagComponentProps) => (
  <div>{label}</div>
);

function renderTags(value: Tag[], getTagProps: AutocompleteGetTagProps) {
  return value.map(({ color, label }, index) => {
    // TS2322: Type '{}' is not assignable to type 'TagComponentProps'.
    // Type '{}' is missing the following properties from type 'Tag': color, label
    const tagProps = getTagProps({ index });

    return (
      <TagComponent key={label} {...tagProps} color={color} label={label} />
    );
  });
}

export const App = () => {
  return (
    <Autocomplete
      options={[]}
      renderTags={renderTags}
      renderInput={() => <input />}
    />
  );
};

Note that your example is not correct, there are no label prop returned by getTagProps.

@oliviertassinari oliviertassinari changed the title AutocompleteGetTagProps type definition could be improved by using a generic [Autocomplete] AutocompleteGetTagProps type definition could be improved Feb 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants