Reputation: 1052
I have been working on Material-UI and trying to use a color system throughout the palette. There seems to be some issue while compilation although it works perfectly in run time. Can someone help me resolve following error:
Error:
Property 'main' does not exist on type 'PaletteColorOptions'.
Property 'main' does not exist on type 'Partial'.(2339)
Here is stackblitz as well: https://stackblitz.com/edit/react-up6bjl-hx1bbh?file=demo.tsx
Code:
import * as React from 'react';
import {
createTheme,
Theme,
ThemeProvider,
PaletteOptions
} from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
declare module '@material-ui/core/styles' {
interface SimplePaletteColorOptions {
lighter?: string;
darker?: string;
}
interface PaletteColor {
lighter?: string;
darker?: string;
}
}
const Default = () : PaletteOptions => {
return {
primary: {
lighter: '#ddd',
light: '#ddd',
main: '#ddd',
dark: '#ddd',
darker: '#ddd'
},
};
};
export default function CustomColor() {
const defaultColors = Default();
const palette: PaletteOptions = {
...defaultColors,
divider: defaultColors.primary?.main, // error in compile. Cannot find 'main'
};
const theme: Theme = createTheme({
palette
});
console.log(theme.palette.primary.light);
return (
<ThemeProvider theme={theme}>
<Button color="primary" variant="contained">
neutral
</Button>
</ThemeProvider>
);
}
Upvotes: 8
Views: 8981
Reputation: 623
To make custom palette colors work with MUI components (i.e. <Button color={'neutral'}>
you also need to augment that component module:
declare module '@mui/material/Button' {
interface ButtonPropsColorOverrides {
neutral: true;
}
}
However, I still had some trouble with Property 'main' does not exist
when using the custom theme value in non-MUI components. I solved this by assigning the custom color to its own typed const and then assigning .main
to a string explicitly:
const selector: PaletteColor | undefined = theme.palette[color as keyof Palette] as PaletteColor;
const colorString: string = selector ? selector.main : 'inherit';
https://mui.com/material-ui/customization/palette/#non-palette-colors
Upvotes: 0
Reputation: 81156
The TypeScript error is unrelated to your module augmentation. The issue is just that defaultColors
is of type PaletteOptions
. PaletteOptions
defines primary to be of type PaletteColorOptions.
Here's the definition of PaletteColorOptions and the types it is built from:
export type PaletteColorOptions = SimplePaletteColorOptions | ColorPartial;
export interface SimplePaletteColorOptions {
light?: string;
main: string;
dark?: string;
contrastText?: string;
}
export type ColorPartial = Partial<Color>;
export interface Color {
50: string;
100: string;
200: string;
300: string;
400: string;
500: string;
600: string;
700: string;
800: string;
900: string;
A100: string;
A200: string;
A400: string;
A700: string;
}
So the TypeScript compiler knows that defaultColors.primary
is either SimplePaletteColorOptions
or ColorPartial
, but it doesn't know which. You are then referencing defaultColors.primary.main
, but that isn't guaranteed to be present unless the type of defaultColors.primary
is SimplePaletteColorOptions
.
You can fix this by using a more specific return type for the Default
function that lets TypeScript know that the type of primary
is SimplePaletteColorOptions
:
interface DefaultPaletteOptions extends PaletteOptions {
primary?: SimplePaletteColorOptions;
}
const Default = (): DefaultPaletteOptions => {
return {
primary: {
lighter: "#ddd",
light: "#ddd",
main: "#ddd",
dark: "#ddd",
darker: "#ddd"
}
};
};
Related answers:
Upvotes: 11