admin管理员组

文章数量:1389762

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
Add a comment  | 

1 Answer 1

Reset to default 0

You 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"
    }
}

本文标签: reactjsTypescript Infer function argument based on same object propertyStack Overflow