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

如何在TypeScript中约束recipes属性值为ingredients的合法键名

解决TypeScript中recipes数组元素必须匹配ingredients键的问题

要让recipes里的数组元素严格对应ingredients的键名,核心是利用TypeScript的键类型推导和泛型来约束类型,以下是两种可行方案:

方案一:泛型通用型定义

把CookBook定义为泛型类型,让它动态捕获ingredients的键集合,这样recipes的数组元素就会被限制为这些键:

// 泛型CookBook类型,IngredientKeys约束为字符串类型
type CookBook<IngredientKeys extends string> = {
  ingredients: Record<IngredientKeys, { vegetal: boolean }>,
  recipes: { [key: string]: IngredientKeys[] }
}

// 定义时无需手动指定泛型,TypeScript会自动推导ingredients的键
const cookbook = {
  ingredients: {
    "tomato": { vegetal: true },
    "cheese": { vegetal: false },
    "lettuce": { vegetal: true },
  },

  recipes: {
    "pizza": ["tomato", "cheese"],
    "salad": ["tomato", "lettuce"]
  }
} satisfies CookBook<string>;

当你在recipes里加入非ingredients的键(比如"pineapple"),TypeScript会直接抛出类型错误:

// 错误示例:"pineapple"不在ingredients的键集合中
const invalidCookbook = {
  ingredients: {
    "tomato": { vegetal: true },
    "cheese": { vegetal: false },
    "lettuce": { vegetal: true },
  },

  recipes: {
    "pizza": ["tomato", "cheese", "pineapple"] // 此处报错
  }
} satisfies CookBook<string>;

方案二:基于现有ingredients推导键类型

如果你的ingredients结构固定,可以先单独定义它,再通过keyof typeof推导键类型,直接约束recipes:

// 先定义具体的ingredients对象
const ingredients = {
  "tomato": { vegetal: true },
  "cheese": { vegetal: false },
  "lettuce": { vegetal: true },
};

// 推导ingredients的键类型
type IngredientKey = keyof typeof ingredients;

// 定义CookBook类型,recipes数组元素必须是IngredientKey
type CookBook = {
  ingredients: typeof ingredients,
  recipes: { [key: string]: IngredientKey[] }
};

// 定义cookbook时自动触发类型检查
const cookbook: CookBook = {
  ingredients,
  recipes: {
    "pizza": ["tomato", "cheese"],
    "salad": ["tomato", "lettuce"]
  }
};

同样,当recipes出现非法键时会立即报错,完美符合你的需求。

内容的提问来源于stack exchange,提问作者UXK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:45:17