无需显式传递泛型,如何自动推断函数参数属性类型?
如何让TypeScript自动推断函数返回值中属性的类型,无需调用方传递泛型?
可以通过给createAction定义与Zod Schema关联的泛型约束,让TypeScript自动完成类型推断,无需手动传递z.infer泛型参数。以下是两种贴合不同需求的实现方案:
方案1:让validator接收Schema解析后的数据类型
如果你的validator需要处理Schema解析后的业务数据,可采用此方案:
import { z } from "zod"; interface Externals<T> { validator: (data: T) => void; } // 泛型T绑定Schema解析后的类型,同时约束schemaValue为对应Zod Schema export async function createAction<T>(schemaValue: z.ZodType<T>): Promise<(externals: Externals<T>) => Promise<void>> { return async (externals: Externals<T>): Promise<void> => { // 示例:解析数据后传入validator(可根据实际业务替换逻辑) const sampleData = { translatedValue: "example" } as T; const parsedData = schemaValue.parse(sampleData); externals.validator(parsedData); }; } // 使用示例 const schemaValue = z.object({ translatedValue: z.string().or(z.number()) }); async function runAction(): Promise<void> { // 无需手动传泛型,TypeScript自动推断T为{ translatedValue: string | number } const action = await createAction(schemaValue); await action({ async validator(data) { // data自动拥有正确类型,支持智能提示 console.log(data.translatedValue.toUpperCase()); // 针对string类型的方法会被正确识别 } }); }
方案2:让validator接收Zod Schema对象本身
如果你的validator需要直接操作Zod Schema对象(比如调用parse、refine等方法),可采用此方案:
import { z } from "zod"; interface Externals<T extends z.ZodTypeAny> { validator: (schema: T) => void; } // 泛型T直接绑定Zod Schema的类型 export async function createAction<T extends z.ZodTypeAny>(schemaValue: T): Promise<(externals: Externals<T>) => Promise<void>> { return async (externals: Externals<T>): Promise<void> => { externals.validator(schemaValue); }; } // 使用示例 const schemaValue = z.object({ translatedValue: z.string().or(z.number()) }); async function runAction(): Promise<void> { const action = await createAction(schemaValue); await action({ async validator(schema) { // schema自动推断为typeof schemaValue,支持调用Zod的所有方法 const validatedData = schema.parse({ translatedValue: 123 }); } }); }
核心原理
- 通过给
createAction定义泛型并添加Zod类型约束,让TypeScript能从传入的schemaValue自动推导泛型的具体类型。 - 函数返回值的类型与泛型直接绑定,确保后续调用
action时,validator的参数类型能被正确推断,无需手动指定泛型。
内容的提问来源于stack exchange,提问作者Shannon Hochkins
相关产品推荐
相关产品推荐

