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

Typescript issues in 10.19.4+ with @mui/material #4293

Closed
akornatskyy opened this issue Feb 22, 2024 · 14 comments
Closed

Typescript issues in 10.19.4+ with @mui/material #4293

akornatskyy opened this issue Feb 22, 2024 · 14 comments
Labels

Comments

@akornatskyy
Copy link

It works as expected with preact version 10.19.3. The issues are reproducable with 10.19.4 - 10.19.6.

Issue 1

<Card component="form" />

cause:

No overload matches this call.
  Overload 1 of 2, '(props: never): Element | null', gave the following error.
    Type 'string' is not assignable to type 'never'.
  Overload 2 of 2, '(props: DefaultComponentProps<CardTypeMap<{}, "div">>): Element | null', gave the following error.
    Type '{ component: string; }' is not assignable to type 'IntrinsicAttributes & CardOwnProps & CommonProps & Omit<HTMLAttributes<HTMLDivElement>, "children" | ... 7 more ... | "raised">'.
      Property 'component' does not exist on type 'IntrinsicAttributes & CardOwnProps & CommonProps & Omit<HTMLAttributes<HTMLDivElement>, "children" | ... 7 more ... | "raised">'.ts(2769)

Issue 2

another issue is related to Button:

<Button>
  test
  <Icon />
</Button>

cause:

No overload matches this call.
  Overload 2 of 3, '(props: { component: React.ElementType; } & ButtonOwnProps & Omit<ButtonBaseOwnProps, "classes"> & CommonProps & Omit<any, "className" | "style" | ... 23 more ... | "startIcon">): Element | null', gave the following error.
    Type 'Element' is not assignable to type 'string'.ts(2769)

Issue 3

and another one:

<Button>
  test
  {disabled && <Icon />}
</Button>

cause:

No overload matches this call.
  Overload 2 of 3, '(props: { component: React.ElementType; } & ButtonOwnProps & Omit<ButtonBaseOwnProps, "classes"> & CommonProps & Omit<any, "className" | "style" | ... 23 more ... | "startIcon">): Element | null', gave the following error.
    Type 'false | Element | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.ts(2769)
@rschristian
Copy link
Member

Hm, odd. Looks like #4239 & #4271 would be the only relevant changes though. Mind going into node_modules & reversing the changes to figure out which one or ones in particular are problematic?

@akornatskyy
Copy link
Author

it is related to #4271, specifically only this one:

export type ComponentPropsWithRef<
C extends ComponentType<any> | keyof JSXInternal.IntrinsicElements
> = C extends (new(props: infer P) => Component<any, any>)
? PropsWithoutRef<P> & RefAttributes<InstanceType<C>>
: ComponentProps<C>;

@rschristian
Copy link
Member

Thanks for finding that!

Will need to figure out an altered implementation I guess.

ryanlchan added a commit to ryanlchan/preact that referenced this issue Mar 31, 2024
@ryanlchan
Copy link

Issue 1 resolved for me by modifying ComponentPropsWithRef as follows (from ryanlchan/preact@8a6b642):

export type ComponentPropsWithRef<
    C extends ComponentType<any> | keyof JSXInternal.IntrinsicElements
> = C extends new (props: infer P) => Component<any, any>
    ? PropsWithoutRef<P> & RefAttributes<InstanceType<C>>
    : PropsWithRef<ComponentProps<C>>;

This matches the implementation in types/react:

type ComponentPropsWithRef<T extends ElementType> = T extends (new(props: infer P) => Component<any, any>)
        ? PropsWithoutRef<P> & RefAttributes<InstanceType<T>>
        : PropsWithRef<ComponentProps<T>>;

I could not get issues 2 and 3 to repro - @akornatskyy could you check if this helps you?

@akornatskyy
Copy link
Author

@ryanlchan : thanks. I rolled your change on top of version 10.20.1. yes, that solved all issues reported earlier.

@akornatskyy
Copy link
Author

@ryanlchan : any update? it is still reproducable with 10.23.1.

@latant
Copy link

latant commented Oct 18, 2024

I could make it work by providing the type parameter:
<Typography<"div"> component="div" variant="h5"/>
However, when the type param and component prop are not given, the props type is resolved as 'any', making the types useless.
Refactoring the OverridableComponent type definition in @mui/material can also solve this issue, like in this .d.ts file: https://gist.github.com/latant/b63c4ca48b6c0b723fcdaac5ed7c77b3
filling the 'component' property still needs the specified type parameter though.

@rschristian
Copy link
Member

Going to close this out as I can no longer reproduce in latest Preact, seems to have been fixed?

import { Card, Button, Icon } from '@mui/material';

export function Tmp() {
    return <Card component="form" />;
}

export function Tmp2() {
    return <Button>test <Icon /></Button>;
}

export function Tmp3() {
    const disabled = true;
    return <Button>test {disabled && <Icon />}</Button>;
}

None of the original 3 cases seem to cause type errors anymore. If anyone can reproduce them, let me know.

@akornatskyy
Copy link
Author

import Fade from '@mui/material/Fade';
import {styled} from '@mui/material/styles';

const Styled = styled(Fade)({});

export function T() {
    const disabled = true;
    return <p>test {disabled && <Styled />}</p>;
}
error TS2769: No overload matches this call...., gave the following error.
    Type 'false | Element | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

@rschristian
Copy link
Member

@akornatskyy I cannot reproduce any type errors with that snippet. Please double check the versions you're using.

@mui/material: 6.1.7
preact: 10.24.3

@akornatskyy
Copy link
Author

Thanks for checking.

It seems the issue was caused by TypeScript incorrectly referencing the wrong line.

image

When I replace onClick with onSubmit it compiles as expected; similarly if I change SubmitEvent to Event.

@rschristian
Copy link
Member

The type error there is entirely correct; a button does not trigger a SubmitEvent, that is only available (AFAIK) through onSubmit.

Generally I'd suggest letting TS infer the type (write an inline function first if you have to) as guessing the parameter type can cause difficult type errors if you're not familiar.

@akornatskyy
Copy link
Author

@rschristian: my confusion was that error points to line 14 instead of 12.

@rschristian
Copy link
Member

Ah, well, not something on our end. Maybe the library tries to derive different children types depending on event props? Not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants