Stop overcomplicating things.
It's crucial to establish a type that both objects must adhere to for accuracy. In Typescript, creating solid data types from the start will benefit you in the long haul.
Define a type like this:
type UITheme = {
background: string,
text: {
primary: string
secondary: string
}
}
Ensure that your objects are constructed correctly using this type.
const lightMode: UITheme = {
background: "white",
text: {
primary: "dark",
secondary: "darkgrey"
},
} as const
const darkMode: UITheme = {
background: "black",
text: {
primary: "white",
},
} as const
// Type error since 'secondary' property is missing in object
// '{ readonly primary: "white"; }'
// which is required based on type
// '{ primary: string; secondary: string; }'.
View playground
If you require the inference of string literal types, utilize a generic function to create and enforce the objects.
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
View playground