Reputation: 379
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"],
Upvotes: 7
Views: 8516
Reputation: 361
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:
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"
}
}
Upvotes: 6
Reputation: 151
I was facing the same issue with my nextjs and monorepo project using pnpm. I've found out a solution.
If you are using MUI, then you need to add this in the root file of your project.
import type {} from "@mui/system";
import type {} from "@emotion/styled";
If you are using Nextjs, then the root file would be layout.tsx file. If you are using React with vite, then I think the root file would be main.ts file.
If you don't want to add the above code snippet to the root of your file, you can simply create typings.d.ts file in the root and add the above code snippet there and you are good to go.
Note: I only tested this on my Nextjs 14 project and monorepo using turbo.
This is the GitHub repository and GitHub discussion if you want to see more detail.
FYI: This solution should be valid for all the packages. This is not limited to just Material UI (MUI).
What is the problem: Main issue is pnpm, which are installing packages as symlinks instead of copying files. Then Typescript follows the symlink and finds out the referenced file is out of the project root, which triggers the error.
Why we are importing type declartions? I think it seems TypeScript to find desired type declarations.
Upvotes: 3
Reputation: 5739
This error usually indicates there are multiple versions of a dependency in the project, e.g. one defined in the package.json of a package, another specified as a dependency in root level package.json. You can verify this by running: yarn why package-name
, e.g. yarn why @mui/system
. In case of mismatching versions you'd see:
├─ my-repo@workspace:packages/react-components [c0f3f]
│ └─ @mui/system@npm:5.10.4 [9e221] (via npm:5.10.4 [9e221])
│
├─ my-repo@workspace:packages/react-components
│ └─ @mui/system@npm:5.10.4 [9e221] (via npm:5.10.4 [9e221])
│
├─ @mui/material@npm:5.10.4
│ └─ @mui/system@npm:5.11.16 (via npm:^5.10.4)
│
└─ @mui/material@npm:5.10.4 [9e221]
└─ @mui/system@npm:5.11.16 [478da] (via npm:^5.10.4 [478da])
Notice how two first entries are using @mui/system 5.10.4, while the latter two use 5.11.16.
To fix it, update the mismatching version you defined in "dependencies" in your package.json to match the one required another library.
Here: yarn workspace @my-repo/react-components add @mui/[email protected]
. Confirm whether it has taken effect by running yarn info package-name
again.
Upvotes: 8