I am trying to infer the output of a zod schema as a parameter to a callback in a mapped type. The variable d
is currently inferred as any
where it should be the shape of the zod schema thats defined in the same object. Is this possible? Heres a minimal example:
import { ComponentType } from "react";
import { z } from "zod";
type Step<
TKey = string,
TSchema extends z.ZodType = z.ZodType,
TProps = unknown
> = {
component: ComponentType<TProps>;
schema: TSchema;
getNextStep?: (data: z.infer<TSchema>) => TKey;
};
type Config<TConfig> = {
[K in keyof TConfig]: TConfig[K] extends Step ? TConfig[K] : unknown;
};
function createConfig<TConfig>(config: Config<TConfig>) {
return config;
}
const config = createConfig({
Step1: {
component: ({ Id }: { Id: string }) => null,
schema: z.object({ userId: z.string() }),
getNextStep: (d) => "Step2", // <---- `d` is inferred as `any`
},
Step2: {
component: ({ userId }: { userId: string }) => null,
schema: z.unknown(),
getNextStep: () => "Step1",
},
});
I am trying to infer the output of a zod schema as a parameter to a callback in a mapped type. The variable d
is currently inferred as any
where it should be the shape of the zod schema thats defined in the same object. Is this possible? Heres a minimal example:
import { ComponentType } from "react";
import { z } from "zod";
type Step<
TKey = string,
TSchema extends z.ZodType = z.ZodType,
TProps = unknown
> = {
component: ComponentType<TProps>;
schema: TSchema;
getNextStep?: (data: z.infer<TSchema>) => TKey;
};
type Config<TConfig> = {
[K in keyof TConfig]: TConfig[K] extends Step ? TConfig[K] : unknown;
};
function createConfig<TConfig>(config: Config<TConfig>) {
return config;
}
const config = createConfig({
Step1: {
component: ({ Id }: { Id: string }) => null,
schema: z.object({ userId: z.string() }),
getNextStep: (d) => "Step2", // <---- `d` is inferred as `any`
},
Step2: {
component: ({ userId }: { userId: string }) => null,
schema: z.unknown(),
getNextStep: () => "Step1",
},
});
Share
Improve this question
asked Mar 13 at 21:24
Moussa HarajliMoussa Harajli
1,5365 gold badges22 silver badges40 bronze badges
1
- If you do not get enough engagement here, consider editing your minimal reproducible example to be a pure TS question without dependencies on frameworks like react or zod. – jcalz Commented Mar 13 at 22:34
1 Answer
Reset to default 0You can try something simpler:
import type { ComponentType } from "react";
import { z } from "zod";
type Step<
TKey = string,
TSchema extends z.ZodType = z.ZodType,
TProps = unknown
> = {
component: ComponentType<TProps>;
schema: TSchema;
getNextStep?: (data: TSchema) => TKey;
};
const step1Schema = z.object({ userId: z.string() });
const step2Schema = z.unknown();
type Config = {
Step1: Step<"Step1", typeof step1Schema, { Id: string }>,
Step2: Step<"Step2", typeof step2Schema, { Id: string }>,
}
const config: Config = {
Step1: {
component: ({ Id }) => null,
schema: step1Schema,
getNextStep: (data) => "Step1"
},
Step2: {
component: ({ Id }) => null,
schema: step2Schema,
getNextStep: (data) => "Step2"
}
}