mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.18k stars 32.08k forks source link

[docs] Passing sx example causes eslint "unsafe spready of 'any' value in an array" error #37730

Open tylersouthard opened 1 year ago

tylersouthard commented 1 year ago

Duplicates

Related page

https://mui.com/system/getting-started/the-sx-prop/#passing-the-sx-prop

Kind of issue

Broken demonstration

Issue description

Perhaps the expectation is that users are not prohibiting the use of the any type via eslint, but if I copy the ListHeader component example from the referenced docs page, eslint marks it as an error. Specifically, the case where sx is an array, eslint sees it as type any[] (see screenshot). I'm wondering if there's a way to make this work with the eslint setting to prevent the use of any?

image

Context 🔦

Attempting to make a component that accepts an sx property and passes it to its first child component (a MUI Box) and add a few style prop settings. See screenshot.

image

mnajdova commented 1 year ago

It doesn't look like this bug report has enough info for one of us to reproduce it.

Please provide a CodeSandbox (https://material-ui.com/r/issue-template-latest), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.

Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve

tylersouthard commented 1 year ago

@mnajdova Here's a link to a CodeSandbox.

My problem with doing a repro is that I can't seem to get CodeSandbox to give eslint errors.

Anyway, in PassingSxProp.tsx on line 20 you can see that sx (when it is an array), is of type any[]. With the eslint rule 'no-unsafe-assignment' (here), eslint throws an error for the code, which was taken from the MUI example, as described in the original description of the issue.

image

andreimatei commented 5 months ago

I'm running into the same issue; the recommended way of passing spreading the sx prop runs afoul of the aforementioned eslint rule. I believe the issue is that the Array.isArray() type guard returns arg is any[], which seems to cause typescript's type inference to infer that the type of sx on the respective branch is any[] (instead of

ReadonlyArray<
      boolean | SystemStyleObject<Theme> | ((theme: Theme) => SystemStyleObject<Theme>)
    >

which is the actual variant of SxProps that is an array. I'm a bit disapointed in the inference.

I couldn't figure out how to get type inference to do the right thing. It seems to me that the the way forward would be for material-ui to provide a type guard function returning this type, and for the examples to reference it.

NayanChauveau commented 1 month ago

Hi everyone,

I see there's been some great discussion around the issue with the sx prop type inference when it's an array, especially in relation to the eslint rule 'no-unsafe-assignment'. I'd like to propose a couple of solutions: a quick fix for now and a more robust long-term solution.

Quick Fix

For an immediate resolution, you can use a custom type guard function instead of `Array.isArray(sx)`. Here's the code snippet:

export function isSxArray(
    sx: SxProps<Theme>,
): sx is ReadonlyArray<
    | boolean
    | SystemStyleObject<Theme>
    | ((theme: Theme) => SystemStyleObject<Theme>)
> {
    return Array.isArray(sx);
}

This should help satisfy the eslint rule by providing a more specific type guard.

Long-Term Solution

To provide a more comprehensive and permanent fix, I suggest making some changes to the type declarations and adding a new exported function:

  1. Update the `SxProps` type declaration:
    
    export type SxPropsArray<Theme extends object> = ReadonlyArray<
      boolean | SystemStyleObject<Theme> | ((theme: Theme) => SystemStyleObject<Theme>)
    >;

/**

  1. Add a new exported function:

    export function isSxArray(
    sx: SxProps<Theme>,
    ): sx is SxPropsArray<Theme> {
    return Array.isArray(sx);
    }
  2. Update the docs accordingly

These changes will enhance type safety and address the type loss issue more effectively.

I'm more than happy to assist further with these changes. Let me know if you'd like me to proceed with a pull request or if there are any other steps required.

Looking forward to your feedback!

Best regards,

Nayan