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

Spreading 2 sx props (one imported, one component prop) creates typescript errors #43991

Closed
MonstraG opened this issue Oct 4, 2024 · 4 comments
Assignees
Labels
support: question Community support but can be turned into an improvement typescript

Comments

@MonstraG
Copy link
Contributor

MonstraG commented Oct 4, 2024

Steps to reproduce

Link to live example: https://stackblitz.com/edit/stackblitz-starters-d2gr1b?file=pages%2Findex.tsx

import { Box, SxProps, Theme } from '@mui/material';
import { FC } from 'react';
import { sharedSx } from '@/foo';

const MyComponent: FC<{ sx: SxProps<Theme> }> = ({ sx }) => {
  return <Box sx={{ ...sharedSx, ...sx }}>box content</Box>;
};
// foo.ts
import type { SxProps, Theme } from '@mui/material/styles';

export const sharedSx: SxProps<Theme> = {
  bgcolor: 'primary.main',
};

Steps:

  1. pnpm install
  2. pnpm build

Current behavior

./pages/index.tsx:11:15
Type error: No overload matches this call.
  Overload 1 of 2, '(props: { component: ElementType<any, keyof IntrinsicElements>; } & BoxOwnProps<Theme> & Omit<any, keyof BoxOwnProps<Theme>>): Element | null', gave the following error.
    Type '{} | { accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 844 more ...; displayPrint?: SystemStyleObject<...> | ... 1 more ... | ((theme: Theme) => ResponsiveStyleValue<...>); } | ... 33 more ... | { ...; }' is not assignable to type 'SxProps<Theme> | undefined'.
      Type '{ accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | Property.AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 875 more ...; [Symbol.unscopables]: { ...; }; }' is not assignable to type 'SxProps<Theme> | undefined'.
        Type '{ accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | Property.AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 875 more ...; [Symbol.unscopables]: { ...; }; }' is not assignable to type 'undefined'.
  Overload 2 of 2, '(props: DefaultComponentProps<BoxTypeMap<{}, "div", Theme>>): Element | null', gave the following error.
    Type '{} | { accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 844 more ...; displayPrint?: SystemStyleObject<...> | ... 1 more ... | ((theme: Theme) => ResponsiveStyleValue<...>); } | ... 33 more ... | { ...; }' is not assignable to type 'SxProps<Theme> | undefined'.
      Type '{ accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | Property.AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 875 more ...; [Symbol.unscopables]: { ...; }; }' is not assignable to type 'SxProps<Theme> | undefined'.
        Type '{ accentColor?: SystemStyleObject<Theme> | ResponsiveStyleValue<readonly string[] | Property.AccentColor | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 875 more ...; [Symbol.unscopables]: { ...; }; }' is not assignable to type 'undefined'.

   9 |
  10 | const MyComponent: FC<{ sx: SxProps<Theme> }> = ({ sx }) => {
> 11 |   return <Box sx={{ ...sharedSx, ...sx }}>box content</Box>;
     |               ^
  12 | };
  13 |
  14 | export default IndexPage;
 ELIFECYCLE  Command failed with exit code 1.

Expected behavior

No crashy

Context

I believe it happens on 6.1.2 (latest v6) and 5.16.7 (latest v5).

Content is rendered correctly if typescript errors are ignored.

Your environment

Lastest versions of everything and tsconfig in repro, but duplicating here anyway:

npx @mui/envinfo
  System:
    OS: Linux 5.0 undefined
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  Browsers:
    Chrome: Not Found
  npmPackages:
    @emotion/react: 11.13.3 => 11.13.3 
    @emotion/styled: 11.13.0 => 11.13.0 
    @mui/material: 6.1.2 => 6.1.2 
    @mui/material-nextjs: 6.1.2 => 6.1.2 
    @types/react: 18.3.11 => 18.3.11 
    react: 18.3.1 => 18.3.1 
    react-dom: 18.3.1 => 18.3.1 
    typescript: 5.6.2 => 5.6.2 
{
	"compilerOptions": {
		"lib": ["dom", "dom.iterable", "esnext"],
		"allowJs": true,
		"skipLibCheck": true,
		"strict": true,
		"noEmit": true,
		"esModuleInterop": true,
		"module": "esnext",
		"moduleResolution": "bundler",
		"resolveJsonModule": true,
		"isolatedModules": true,
		"jsx": "preserve",
		"incremental": true,
		"plugins": [
			{
				"name": "next"
			}
		],
		"paths": {
			"@/*": ["./*"]
		}
	},
	"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
	"exclude": ["node_modules"]
}

Search keywords: sx spread types typescript import

@MonstraG MonstraG added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Oct 4, 2024
@MonstraG MonstraG changed the title Spreading 3 sx props creates typescript errors Spreading 2 sx props (one imported, one component prop) creates typescript errors Oct 4, 2024
@mnajdova
Copy link
Member

mnajdova commented Oct 5, 2024

The SxProps can be an object, function or an array, you need to make sure all of these different types are accounted for when merging the two sx props, e.g. check https://github.com/mui/material-ui/blob/master/docs/data/system/flexbox/AlignItems.tsx#L25.

Alternatively you can restrict your app to only accept the object type if that is what you intend to use in these scenarios. Check the type for more details. You can e.g. use the SystemStyleObject<Theme> as a type instead, but make sure you don't have instances where the sx prop is not an object.

@MonstraG
Copy link
Contributor Author

MonstraG commented Oct 5, 2024

What is weird to me is that if I put it in the same file:

const sharedSx: SxProps<Theme> = {
  bgcolor: 'primary.main',
};

const MyComponent: FC<{ sx: SxProps<Theme> }> = ({ sx }) => {
  return <Box sx={{ ...sharedSx, ...sx }}>box content</Box>;
};

then it works.

It also seems that

import type { SystemStyleObject } from '@mui/material/styles';

Is not available, and I have to do

import type { SystemStyleObject } from '@mui/system';

But okay, I think I'll do the latter.

If there is nothing that looks wrong with that to you, the issue can be closed.

@siriwatknp
Copy link
Member

siriwatknp commented Oct 7, 2024

@MonstraG Please follow this: https://mui.com/system/getting-started/the-sx-prop/#passing-the-sx-prop

const MyComponent: FC<{ sx: SxProps<Theme> }> = ({ sx }) => {
  return <Box sx={[sharedSx, …Array.isArray(sx) ? sx : [sx] ]}>box content</Box>;
};

I'm closing this issue.

@siriwatknp siriwatknp added support: question Community support but can be turned into an improvement and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Oct 7, 2024
Copy link

github-actions bot commented Oct 7, 2024

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

Note

@MonstraG How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support: question Community support but can be turned into an improvement typescript
Projects
None yet
Development

No branches or pull requests

5 participants