reactjstypescripttypesmaterial-uistyled-components

Material UI styled component - "The inferred type of X cannot be named without a reference..."


How is this TS issue resolved? My styled component is exported from a style.ts file and used inside the index.tsx file of my React component:

style.ts:

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

type CardProps = {
    theme?: Theme;
    selected: boolean;
};

const Card = styled('div', {
    shouldForwardProp: (p) => !!p
})(({ theme, selected }: CardProps) => ({
    display: 'flex',
    flexDirection: 'column',
    padding: theme?.spacing(2),
    width: theme?.spacing(39.5),
    boxShadow: theme?.shadows[2],
    color: theme?.palette.grey[50],
    borderRadius: theme?.spacing(0.5),
    margin: `${theme?.spacing()} ${theme?.spacing(2)}`,
    ...(selected && {
        background: theme?.palette.grey[100],
        color: theme?.palette.getContrastText(theme?.palette.grey[100])
    }),
    ...(!selected && {
        cursor: 'pointer',
        border: `1px solid #DEE4EA`
    }),
    '&:hover': {
        ...(!selected && { color: theme?.palette.grey[100] })
    }
}));

export { Card }

index.tsx

import { Card } from './style';

const ExperimentCard = ({
    id,
    selected,
    handleSelectCard,
}: Props) => (
 <Card data-cy="experiment-card" id={id} selected={selected} onClick={() => handleSelectCard(id)}>
    ...
</Card>

TS issue:

Plugin typescript: @rollup/plugin-typescript TS2742: The inferred type of 'Card' cannot be named without a reference to '@mui/material/node_modules/@mui/system'. This is likely not portable. A type annotation is necessary.

One suggestion I have found, was adding the suggested reference into the tsconfig.json file like below, but with no luck.

"types": ["@mui/material/node_modules/@mui/system"],

Solution

  • I had this issue using mui styled with pnpm in a monorepo setting. After some digging it seems to be caused by typescript not playing well with nested transitive dependencies.

    Here are some related issues on github where people discuss the root of the problem and pose some solutions:

    Typescript Issue #36800

    Typescript Issue #30858

    I couldn't find a convenient solution that worked for pnpm, besides configuring nodelinker=hoisted, which defeats the purpose of using pnpm in the first place.

    EDIT

    It seems that installing @mui/system as a direct dependency worked, since @mui/system is now at the root level of node_modules. I had to reload my project window aswell to get typescript to play nice with vscode. This might cause problems however if the version you install as a direct dependency is incompatible with your version of @mui/material, so be careful if you take this approach.

    In your case, it might be better to just map @mui/system directly to the nested dependency in your root level tsconfig.json file:

    "compilerOptions": {
        "baseUrl": ".",
        "paths:": {
            "@mui/system": "@mui/material/node_modules/@mui/system"
        }
    }