如何在TypeScript中让Yup Schema数组字段匹配Product接口类型?
实现Yup Schema与Product接口的强类型绑定
核心问题分析
要让yup.InferType<typeof productSchema>完全匹配Product接口(尤其是attributes: Attribute[]的类型),关键在于正确关联数组字段的子Schema,并通过类型约束强制Schema与接口的一致性。
分步解决方案
1. 定义基础接口
先明确业务模型的类型:
interface Attribute { id: string; name: string; value: string; } interface Product { id: string; name: string; price: number; attributes: Attribute[]; }
2. 编写子Schema(Attribute)
为数组元素单独定义Schema,确保内部类型被正确推断:
import * as yup from 'yup'; const attributeSchema = yup.object({ id: yup.string().required(), name: yup.string().required(), value: yup.string().required(), });
3. 编写Product Schema(关键:关联子Schema)
使用yup.array().of()指定数组元素的Schema,避免默认的any[]或AssertsShape[]类型:
const productSchema = yup.object({ id: yup.string().required(), name: yup.string().required(), price: yup.number().positive().required(), // 用of()关联attributeSchema,确保推断类型为Attribute[] attributes: yup.array().of(attributeSchema).required(), });
4. 添加强类型约束(强制Schema与接口一致)
通过自定义类型断言,当Product接口新增字段但未同步到Schema时,TypeScript会直接报错:
// 约束Schema的推断类型必须严格匹配目标接口 type AssertSchemaMatches<T, S extends yup.Schema<T>> = S; // 应用约束,不匹配则触发类型错误 const typedProductSchema: AssertSchemaMatches<Product, typeof productSchema> = productSchema;
5. 验证推断类型
此时yup.InferType的结果会完全匹配Product接口:
type ProductSchemaType = yup.InferType<typeof typedProductSchema>; // ProductSchemaType 结构与 Product 完全一致,attributes 类型为 Attribute[]
强绑定效果验证
如果给Product接口新增字段(比如description: string)但未更新Schema,TypeScript会立即抛出错误:
Property 'description' is missing in type '{ id: StringSchema<string, AnyObject, undefined, "">; name: StringSchema<string, AnyObject, undefined, "">; price: NumberSchema<number, AnyObject, undefined, "">; attributes: ArraySchema<...>; }' but required in type 'Schema<Product, AnyObject, Product, "">'.
内容的提问来源于stack exchange,提问作者M.Ubeyd
相关产品推荐
相关产品推荐

