You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:50:35