I have two theme objects:
const lightMode = {
background: "white",
text: {
primary: "dark",
secondary: "darkgrey"
},
} as const
const darkMode = {
background: "black",
text: {
primary: "white",
},
} as const
I want to get a type error if the lightMode object (default theme, which everyone will modify first) does not have the same shape as the darkMode object.
This will help people remember to update darkMode with some color values, if they add some new theme color to lightMode.
CodePudding user response:
You're overthinking this.
What you have a type that both object must implement to be correct. Like most things in Typescript, defining good data types up front will make things nice for you in the long run.
Make a type like:
type UITheme = {
background: string,
text: {
primary: string
secondary: string
}
}
And now use it to make sure your objects are made properly.
const lightMode: UITheme = {
background: "white",
text: {
primary: "dark",
secondary: "darkgrey"
},
} as const
const darkMode: UITheme = {
background: "black",
text: {
primary: "white",
},
} as const
// Property 'secondary' is missing in type
// '{ readonly primary: "white"; }'
// but required in type
// '{ primary: string; secondary: string; }'.
Or if you need the string literal types inferred, then use a generic function to create the objects and enforce the types.
type UITheme = {
background: string,
text: {
primary: string
secondary: string
}
}
const createUIMode = <T extends UITheme>(theme: T) => theme
const lightMode = createUIMode({
background: "white",
text: {
primary: "dark",
secondary: "darkgrey"
},
} as const)
const darkMode = createUIMode({
background: "black",
text: {
primary: "white",
},
} as const)
// error
CodePudding user response:
Here's my first attempt:
type NormalizeThemeConstType<someTheme extends object> = Writable<
Schema<someTheme, string>
>;
const testAssignment: NormalizeThemeConstType<typeof darkMode> =
lightTheme as NormalizeThemeConstType<typeof lightMode>;
The type errors seem crazy at first, but as is usually the case, looking at the end of the error revealed, on of our themes is missing a property from the other!