0

I want to make collection of all MUI(v5) sx props out side of component. like following

const styles = { // HOW TO TYPE THIS VARIABLE
  sectionOne: { // type of SXProps<Theme>
    
  },
  // ...
};

const Component: = () => {
  return (
    <>
      <Box sx={styles.sectionOne}></Box>
      // ....
    </>
  )
}

I've created following type

type StylesCollection = {
  [key: string]: SxProps<Theme>
};

This helps when writing inside styles, but doesn't autocompletes when using that.

In this scenario how to type the styles variable, so autosuggest is available when using it (in component / elements sx prop. Like using in the Box component above.

Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
Md. A. Apu
  • 769
  • 10
  • 30

2 Answers2

1

Currently in TypeScript 4.8, we have to use a function:

function createStyles<T extends Record<string, SxProps<Theme>>>(styles: T) { return styles; }

const styles = createStyles({ ... });

However, in TypeScript 4.9, we get the new satisfies operator, allowing us to do this:

const styles = {
    // ...
} satisfies Record<string, SxProps<Theme>>;

Or if you're brave enough, you could explicitly annotate your object:

const styles: {
    sectionOne: SxProps<Theme>;
    ...
} = {};

but I don't think that's feasible for larger objects...

kelsny
  • 23,009
  • 3
  • 19
  • 48
  • Perfect,... but could you please explain a bit (of TS 4.8 solution), so I can learn. If you explain why my type `StylesCollection ` is not working, I could understand it better – Md. A. Apu Sep 28 '22 at 08:35
  • 1
    @APu Currently, you are overwriting the types of your object with `StylesCollection`, and so it becomes `{ [key: string]: ... }` instead of having your original keys. To sum it up, you want your object to *satisfy* (conform to) a certain type. That's where you would use the function. You're just checking if it is assignable to the type, then returning the original. In 4.9, we can use `satisfies` as a shortcut for this instead of a function. – kelsny Sep 28 '22 at 13:00
0

theme.ts

import { createTheme, SxProps } from '@mui/material/styles'

export const theme = createTheme({...})

declare module '@mui/material' {
  type StyleProps = Record<string, SxProps<typeof theme>>
}

some-components.tsx

import { StyleProps, Box } from '@mui/material'

const styles: StyleProps = {
  button: {
    typography: 'h2',
    py: 2,
  }
}

function SomeComponent() {
  return <Box sx={styles.button}>text</Box>
}
  • Good solution but it doesn't cover 1st level keys `button` in this case, when try to use it in component like `styles.but` ... – Md. A. Apu Mar 17 '23 at 14:52