There are three simple types available:
const structureTypes = z.enum(["atom","molecule"])
const atomTypes = z.enum(["oxygen","hydrogen"])
const moleculeTypes = z.enum(["water","ammonia"])
The goal is to define a type for a cache where the keys correspond to the names of atoms or molecules, nested within their respective structure types. The object structure should look like this:
{
atom: { oxygen: "abdshc7823", hydrogen: "hjksdfkjh" }
molecule: { water: "hjfsdlkjj3", ammonia: "trewuivx67" }
}
Using Zod's record()
method, we can come close:
const structureIdCacheSchema = z.record(
structureTypes,
z.record(z.union([atomTypes, moleculeTypes]), z.string())
)
export type StructureIdCache = z.infer<typeof structureIdCacheSchema>;
However, the issue arises when the keys for the nested objects are not restricted to their corresponding structure type. Is there a way to create an alias for keys in a similar manner with Zod record?
I have also attempted another approach as shown below:
export const structureTypeCacheSchema = z.object({
atom: z.record(atomTypeSchema, z.string()),
molecule: z.record(moleculeTypeSchema, z.string()),
})
This method requires separate maintenance from the enums but encounters an error when trying to access the nested elements:
Element implicitly has an 'any' type because expression of type "oxygen" | "hydrogen" | "water" | "ammonia" cannot be used to index type 'Partial<Record<"paragraph" | "oxygen" | "hydrogen", string>> | Partial<...>'.
Property 'oxygen' does not exist on type 'Partial<Record<"oxygen" | "hydrogen", string>> | Partial<...>'.ts(7053)