我使用
zod
库进行模式验证,并定义了两个模式:FormFactorDevice
和 FormFactor
。我还实现了一个 selectFormFactorDevice
函数,根据给定的 FormFactorDevice
从 deviceType
对象中选择一个值。
但是,
selectFormFactorDevice
的返回值被推断为any
类型,而我希望它是string | undefined
,因为我使用z.string()
作为fieldSchema
参数。
这是代码:
export const FormFactorDevice = <T extends z.ZodTypeAny>(fieldSchema: T) =>
z.object({
all: z.optional(fieldSchema),
phone: z.optional(fieldSchema),
smalltablet: z.optional(fieldSchema),
tablet: z.optional(fieldSchema),
laptop: z.optional(fieldSchema),
desktop: z.optional(fieldSchema),
});
export const FormFactor = <Z extends z.ZodTypeAny>(fieldSchema: Z) =>
z.object({
isFormFactor: z.literal(true).default(true),
all: z.optional(fieldSchema),
landscape: z.optional(FormFactorDevice(fieldSchema)),
portrait: z.optional(FormFactorDevice(fieldSchema)),
});
// FormFactorDevice could receive very complicated schema
const b = FormFactorDevice(z.string()).parse({
all: '100',
smalltablet: '200',
phone: '300',
});
export const selectFormFactorDevice = <T extends z.ZodTypeAny>(
formFactorDevice: z.infer<ReturnType<typeof FormFactorDevice<T>>>,
deviceType: 'all' | 'phone' | 'smalltablet' | 'tablet' | 'laptop' | 'desktop'
): z.infer<T> | undefined => {
return formFactorDevice[deviceType];
};
const d = selectFormFactorDevice(b, 'all'); // d is inferred as `any` type
如何修改
selectFormFactorDevice
函数以返回正确的类型(在本例中为 string | undefined
)?
注意:我尝试使用 z.infer 和 ReturnType
我知道
selectFormFactorDevice<z.ZodString>(b, 'all')
应该可以工作,但我希望我的函数足够智能以自动推断类型
您可以尝试将代码复制并粘贴到此处的 zod Playground:https://stackblitz.com/edit/typescript-rqwgxo?file=index.ts
selectFormFactorDevice
函数的实现非常简单(它只是一个属性访问)。我假设你想让它的打字做两件事:
FormFactorDevice
函数创建的模式解析的对象。我认为这些类型至少可以很好地满足这两个要求:
export const selectFormFactorDevice = <
TFormFactorDevice extends z.infer<
ReturnType<typeof FormFactorDevice<ZodTypeAny>>
>,
TDeviceType extends
| 'all'
| 'phone'
| 'smalltablet'
| 'tablet'
| 'laptop'
| 'desktop'
>(
formFactorDevice: TFormFactorDevice,
deviceType: TDeviceType
) => {
return formFactorDevice[deviceType];
};
对
TFormFactorDevice
的约束表达了第 1 点(尽管它可能以不完整的方式实现;我不是 Zod 类型方面的专家)。对 TDeviceType
使用泛型参数 deviceType
可确保正确推断返回类型(第 2 点);它就变成了TFormFactorDevice[TDeviceType]
。