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

[POC] Fix Interpolation types #45478

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

siriwatknp
Copy link
Member

@mui-bot
Copy link

mui-bot commented Mar 4, 2025

Netlify deploy preview

https://deploy-preview-45478--material-ui.netlify.app/

Bundle size report

No bundle size changes (Toolpad)
No bundle size changes

Generated by 🚫 dangerJS against 1537b32

@@ -42,7 +42,7 @@ const items = [
const Chip = styled(MuiChip)(({ theme }) => ({
variants: [
{
props: ({ selected }) => selected,
props: ({ selected }) => !!selected,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to fix this because the type of selected is boolean | undefined.

Should we loosen the type like of props? to be () => boolean | null | undefined?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the !! to cast into boolean

| ComponentSelector
| Keyframes
| SerializedStyles
| CSSPropertiesWithMultiValues
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a myth to me. If not adding CSSPropertiesWithMultiValues explicitly as a union, the spec fail for recreating nested theme.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean with "myth"?

Copy link
Member Author

@siriwatknp siriwatknp Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I thought that CSSObject is enough because it extends CSSPropertiesWithMultiValues. However, if I excluded CSSPropertiesWithMultiValues from the union type, I got this error from createTheme.spec:

image

Here is the full error:

Argument of type 'Theme' is not assignable to parameter of type 'Omit<ThemeOptions, "components"> & Pick<CssVarsThemeOptions, "colorSchemes" | "defaultColorScheme" | "components"> & { ...; }'.
  Type 'Theme' is not assignable to type 'Pick<CssVarsThemeOptions, "colorSchemes" | "defaultColorScheme" | "components">'.
    Types of property 'components' are incompatible.
      Type 'Components<BaseTheme> | undefined' is not assignable to type 'Components<Omit<Theme, "palette" | "components"> & CssVarsTheme> | undefined'.
        Type 'Components<BaseTheme>' is not assignable to type 'Components<Omit<Theme, "palette" | "components"> & CssVarsTheme>'.
          Types of property 'MuiAlert' are incompatible.
            Type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined; variants?: { ...; }[] | undefined; } | undefined' is not assignable to type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined; variants?: { ...; }[] | undefined; } | undefined'.
              Type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined; variants?: { ...; }[] | undefined; }' is not assignable to type '{ defaultProps?: Partial<AlertProps> | undefined; styleOverrides?: Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined; variants?: { ...; }[] | undefined; }'.
                Types of property 'styleOverrides' are incompatible.
                  Type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>> | undefined' is not assignable to type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>> | undefined'.
                    Type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", BaseTheme>>' is not assignable to type 'Partial<OverridesStyleRules<keyof AlertClasses, "MuiAlert", Omit<Theme, "palette" | "components"> & CssVarsTheme>>'.
                      Types of property 'root' are incompatible.
                        Type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: BaseTheme; }>' is not assignable to type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: Omit<Theme, "palette" | "components"> & CssVarsTheme; }>'.
                          Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is not assignable to type 'Interpolation<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { theme: Omit<Theme, "palette" | "components"> & CssVarsTheme; }>'.
                            Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is not assignable to type 'Keyframes'.
                              Type 'CSSObject & { variants?: { props: Partial<AlertProps & Record<string, unknown> & { ownerState: AlertProps & Record<string, unknown>; } & { ...; }> | ((props: Partial<...> & { ...; }) => boolean); style: CSSObject | ((args: { ...; }) => CSSObject); }[] | undefined; }' is missing the following properties from type '{ name: string; styles: string; anim: number; toString: () => string; }': name, styles, animts(2345)

I don't fully understand why.

Copy link
Member

@DiegoAndai DiegoAndai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look at this @siriwatknp! 😊

I have a couple of questions

| Keyframes
| SerializedStyles
| CSSPropertiesWithMultiValues
| (CSSObject & {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a benefit in inlining the variants here instead of defining it separately?

Copy link
Member Author

@siriwatknp siriwatknp Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required, otherwise variants is not type-safety. You can try in this Playground

@DiegoAndai
Copy link
Member

Hey @siriwatknp! I took a look at this, and I managed to remove CSSPropertiesWithMultiValues from Interpolation by removing components from the Theme interface, see daa9579.

The CssVarsTheme and Joy's Theme types do not have the components property, so I wonder if it being included in Material's Theme was a mistake.

  1. Do you think this is the correct approach?
  2. This fixed the createTheme(theme issue, but it brought up a bunch of other ones 😅 I will continue taking a look on Monday

@siriwatknp
Copy link
Member Author

siriwatknp commented Mar 10, 2025

Hey @siriwatknp! I took a look at this, and I managed to remove CSSPropertiesWithMultiValues from Interpolation by removing components from the Theme interface, see daa9579.

I suggest not removing it as it will introduce another issue for people who read theme.components.* like this:

const theme = createTheme({
  component: {}
})

console.log(theme.components); // << TS error.

Also, removing the components is technically incorrect because the theme object contains components node (in JS).

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

Successfully merging this pull request may close these issues.

3 participants