当架构在父函数中定义时,如何根据指定的函数参数推断类型?我正在尝试实现工厂模式,但遇到类型推断问题。这是我想要实现的目标的示例:
import { z } from 'zod';
export const makeClient = <T extends string>({
schemas,
}: {
schemas: {
[key in T]: z.ZodSchema;
};
}) => {
type Keys = keyof typeof schemas;
type Values<K extends Keys> = z.infer<typeof schemas[K]>;
return {
async findOne<K extends Keys>({
name,
filter,
}: {
name: K;
filter: Values<K>;
}) {
return { name, filter };
},
};
};
const client = makeClient({
schemas: {
test: z.object({
value: z.number(),
}),
},
});
client.findOne({
name: "test", // this is inferred
filter: {
// not inferred
}
})
我相信在这种情况下应该可以实现类型推断,但我很难弄清楚如何实现。任何指导将不胜感激。
我整理了一个由架构映射驱动的客户端草图,该架构映射从架构映射中推断键以驱动函数参数中的智能感知,并从架构结构推断返回类型。
我无法轻松地与原始实现保持一致,因为 findOne 似乎没有执行任何操作,因此没有任何与运行时模式的实际绑定。相比之下,下面的示例对检索到的数据进行运行时检查(使用运行时模式),然后从中推断出类型。
import { z, type ZodSchema} from 'zod';
import axios from 'axios'
type RecordKey<R> = R extends Record<infer K, unknown> ? K : never
export const makeClient = <const R extends Record<string, ZodSchema<unknown>>>(schemas:R) => {
return {
async retrieve<K extends RecordKey<R>>(key: K, id:string): Promise<z.infer<R[K]>>{
const value = await axios.get(`/item/${key}/${id}`)
return schemas[key].parse(value.data)
}
};
};
const client = makeClient(
{
accumulator: z.object({
count: z.number(),
}),
} as const);
const retrieved = await client.retrieve("accumulator", "48092234")
您可以对其进行实验,并在 https://tsplay.dev/WoebgN
查看密钥和返回类型推断