Skip to content

Typescript error when passing forwardRef components to MUI slots #44952

@khanilov

Description

@khanilov

Steps to reproduce

Steps:

  1. Open this link to live example: https://codesandbox.io/p/sandbox/typescript-playground-export-forked-8glplv
  2. Check typescript issues

Current behavior

Type 'ForwardRefExoticComponent<RefAttributes<HTMLDivElement>>' is not assignable to type 'ElementType<StepIconProps, keyof IntrinsicElements> | undefined'.
  Type 'ForwardRefExoticComponent<RefAttributes<HTMLDivElement>>' is not assignable to type 'FunctionComponent<StepIconProps>'.
    Types of property 'propTypes' are incompatible.
      Type 'WeakValidationMap<RefAttributes<HTMLDivElement>> | undefined' is not assignable to type 'WeakValidationMap<StepIconProps> | undefined'.
        Type 'WeakValidationMap<RefAttributes<HTMLDivElement>>' is not assignable to type 'WeakValidationMap<StepIconProps>'.
          Types of property 'ref' are incompatible.
            Type 'Validator<LegacyRef<HTMLDivElement> | undefined> | undefined' is not assignable to type 'Validator<Ref<unknown> | undefined> | undefined'.
              Type 'Validator<LegacyRef<HTMLDivElement> | undefined>' is not assignable to type 'Validator<Ref<unknown> | undefined>'.
                Type 'LegacyRef<HTMLDivElement> | undefined' is not assignable to type 'Ref<unknown> | undefined'.
                  Type 'string' is not assignable to type 'Ref<unknown> | undefined'.typescript(2322)

Expected behavior

Same constructions worked in material@5

Default components itself wrapped in forwardRef so I would expect this wrapping be acceptable.

From MUI source code:

const StepIcon = React.forwardRef(function StepIcon(inProps, ref) {

Context

After upgrade to material@6 typescript complains about components that was wrapped in forwardRef being passed to slot props, both deprecated one, like: StepIconComponent={xxx}, and new one, like: slots={{ stepIcon: xxx }}.

Seems to be only applicable for slots that have React.ElementType with arguments, like: React.ElementType<StepIconProps>;. Slots without them works fine, most likely because this argument becomes any by default.

Tested with StepLabel and Tooltip components.

Your environment

npx @mui/envinfo
 System:
    OS: macOS 15.1.1
  Binaries:
    Node: 20.16.0 - ~/.nvm/versions/node/v20.16.0/bin/node
    npm: 10.8.1 - ~/.nvm/versions/node/v20.16.0/bin/npm
    pnpm: 9.15.2 - ~/.nvm/versions/node/v20.16.0/bin/pnpm
  Browsers:
    Chrome: 131.0.6778.205
    Edge: Not Found
    Safari: 18.1.1
  npmPackages:
    @emotion/react:  11.14.0 
    @emotion/styled:  11.14.0 
    @mui/core-downloads-tracker:  6.3.0 
    @mui/icons-material:  6.3.0 
    @mui/material:  6.3.0 
    @mui/private-theming:  6.3.0 
    @mui/styled-engine:  6.3.0 
    @mui/system:  6.3.0 
    @mui/types:  7.2.20 
    @mui/utils:  6.3.0 
    @types/react: ^18.3.12 => 18.3.12 
    react: ^18.3.1 => 18.3.1 
    react-dom: ^18.3.1 => 18.3.1 
    styled-components:  5.3.3 
    typescript: ^5.5.3 => 5.5.3

Search keywords: types, typescript, ref, forward, slot

Metadata

Metadata

Assignees

Labels

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions