reactjs - Svårighet att implementera Typescript-förstärkning för mitt MUI-tema
Jag har ett anpassat tema med några extra nycklar/värden som lagts till i temat. Detta orsakar TS-fel när jag försöker använda designtoken i min app. Jag vet att jag behöver använda modulförstärkning för att fixa det, men ärligt talat är jag så förvirrad över var detta ska placeras eller hur det skulle göras korrekt. Jag tycker att dokumentationen är väldigt knapphändig om ämnet, och andra Stack Overflow-inlägg är lika kortfattade med lite kontext om varför eller var de får elementen definierade inom sina modulförstärkta teman. Temat jag byggde är nedan för referens. Tack på förhand, all hjälp uppskattas.
Felet jag får är en variation av detta nedan för varje anpassad temaegenskap:
Type '{ main: string; secondary: string; nav: { main: string; active: string; inactive: string; }; }' is not assignable to type 'Partial<TypeBackground>'.
Object literal may only specify known properties, and 'main' does not exist in type 'Partial<TypeBackground>'
Mitt nuvarande tema är nedan:
const muiTheme = createTheme({
palette: {
primary: { // orange
main: '#ff5e3d',
contrastText: '#e3e8f0'
},
secondary: { // black
main: '#585858',
contrastText: '#e3e8f0'
},
background: {
//@ts-ignore
main: '#FFFFFF', //white
secondary: "#f1f5f9", //lightblue
nav: {
main: '#1e293b',
active: '#0f172a',
inactive: '#1e293b'
}
},
info: undefined,
text: {
primary: "#11142d",
secondary: "#fff",
//@ts-ignore
nav: "#64748b",
meta: "#94a3b8"
},
icons: {
active: {
primary: '#ff5e3d',
secondary: '#ffffff',
},
inactive: {
primary: '#94a3b8',
secondary: '#475569',
}
},
contrastThreshold: 1,
tonalOffset: 0.2,
},
typography: {
fontFamily: ['Gotham', 'Mulish', 'Helvetica', 'Arial', 'sans-serif'].join(","),
h1: {
fontFamily: "Gotham, Helvetica",
fontWeight: 700,
lineHeight: '24px',
fontSize: '16px',
textTransform: "uppercase",
},
h2: {
fontFamily: "Gotham, Helvetica",
fontWeight: 400,
lineHeight: '24px',
fontSize: '16px',
},
h3: {
fontFamily: "Mulish, Arial",
fontWeight: 700,
lineHeight: '24px',
fontSize: '16px',
textTransform: "uppercase",
},
subtitle1: {
fontFamily: "Gotham, Helvetica",
fontWeight: 400,
lineHeight: '19.5px',
fontSize: '13px',
},
body1: {
fontFamily: "Mulish, Arial",
fontWeight: 400,
lineHeight: '21px',
fontSize: '14px',
},
h4: undefined,
h5: undefined,
h6: undefined,
body2: undefined,
subtitle2: undefined,
caption: undefined,
},
components: {
MuiCssBaseline: {
styleOverrides: `${[Gotham, Mulish]}`,
},
MuiButton: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
fontFamily: "Mulish, Arial",
fontWeight: 700,
lineHeight: '15.6px',
fontSize: '13px',
paddingY: 8,
paddingX: 12,
//@ts-ignore
borderColor: theme.palette[ownerState.color].main,
borderRadius: 22.5,
borderWidth: 2,
"&:hover": {
borderWidth: 2
}
}),
},
},
// change other base components here
},
});
REDIGERA: Jag får också ett typfel som indikerar att icon does not exist on type Palette. Jag använder useTheme-hooken för att hämta theme-objektet så att jag kan få temavärdena för en SVG som tar två färgparametrar. Om aktiv, ändras färgerna på SVG:en. Detta objekt skickas till den anpassade ikonkomponenten och färgerna destruktureras, det fungerar för närvarande förutom TS-felet. Koden för den aktiva brytaren där TS-felet uppstår, finns nedan:
const isActive = (
active: boolean,
theme: Theme,
): {
background: string;
iconPrimary: string;
iconSecondary: string;
} => {
return active
? {
//@ts-ignore
iconPrimary: theme.palette.icons.navIcon.active.primary,
//@ts-ignore
iconSecondary: theme.palette.icons.navIcon.active.secondary,
}
: {
//@ts-ignore
iconPrimary: theme.palette.icons.navIcon.inactive.primary,
//@ts-ignore
iconSecondary: theme.palette.icons.navIcon.inactive.secondary,
};
};
Svar #1
Prova följande. Det borde fungera!
Koden nedan utökar de nödvändiga gränssnitten (Mer om utökning i de officiella dokumenten):
declare module "@mui/material" {
export interface TypeBackground {
main: string;
secondary: string;
nav: {
main: string;
active: string;
inactive: string;
}
}
export interface PaletteOptions {
icons: {
active: {
primary: string;
secondary: string;
},
inactive: {
primary: string;
secondary: string;
},
}
}
export interface TypeText {
nav: string;
meta: string;
}
export interface Palette {
icons: PaletteOptions['icons'];
}
}
Kodsnuttarna nedan åtgärdar felen:
borderColor: ownerState.color && ownerState.color !== 'inherit'
? theme.palette[ownerState.color].main
: undefined,
Och :
const isActive = (
active: boolean,
theme: Theme,
): {
background?: string;
iconPrimary: string;
iconSecondary: string;
} => {
return active
? {
iconPrimary: theme.palette.icons.active.primary,
iconSecondary: theme.palette.icons.active.secondary,
}
: {
iconPrimary: theme.palette.icons.inactive.primary,
iconSecondary: theme.palette.icons.inactive.secondary,
};
};
