Reputation: 1516
I have a simple helper function to capture a type for a configuration object. The configuration object has a couple restrictions:
I need to infer the type of the zod schema so that getNextStep is aware of the data for that particular step. No matter how I try to capture the generic for the zod schema, it always resolves to z.ZodType
import { z } from "zod";
type Config<TKey extends string> = {
[K in TKey]: {
id: string;
getNextStep?: (
data?: unknown <--- Infer this type from the provided schema, if available.
) => TKey extends infer U extends string ? Exclude<U, K> | null : never;
schema?: z.ZodType;
};
};
function createConfig<TKey extends string>(config: Config<TKey>) {
return config;
}
const Config = createConfig({
Step1: {
id: "Step1",
schema: z.object({ name: z.string() }),
getNextStep: () => "Step2",
},
Step2: {
id: "Step2",
schema: z.object({ enabled: z.boolean() }),
},
});
Upvotes: 0
Views: 24
Reputation: 1516
I was able to achieve what I wanted with the following type:
import { z } from "zod";
function createConfig<
TSchema extends z.ZodType,
TConfig extends Record<string, TSchema>
>(config: {
[K in keyof TConfig]: {
id: string;
schema?: TConfig[K];
getNextStep?: (
data?: z.infer<TConfig[K]>
) => Exclude<keyof TConfig, K> | null;
};
}) {
return config;
}
const Config = createConfig({
Overview: {
id: "Overview",
schema: z.object({ name: z.string() }),
getNextStep: (data) => "Main",
},
Main: {
id: "Main",
schema: z.object({ enabled: z.boolean() }),
},
});
Upvotes: 0