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

TypeScript:基于父对象键约束子对象属性值

TypeScript 类型约束:子对象属性与父对象键名一致的实现方案

需求概述

我需要在项目中强制执行这样的类型规则:子对象中的name字符串属性必须与其父对象对应的键名完全相同。简化示例如下:

const profile = {
   languages: {
      // 合法:键名与name一致
      english: { name: "english" },
      // 不合法:键名是"spanish"但name是"italian",二者必须匹配
      spanish: { name: "italian" }
   }
}

已知的泛型实现方式

我已经知道可以通过泛型来实现这个约束,但问题在于我的项目中Profile和Languages之间存在多层嵌套结构,传递泛型参数会非常繁琐:

export type Profile<TLanguageNames> = {
  languages: Languages<TLanguageNames>;
};

export type Languages<TLanguageNames> = {
  readonly [TLanguageName in keyof TLanguageNames]?: {
    readonly name: TLanguageName;
  };
};

// 使用时需要手动指定泛型参数
const fields: Profile<{ english: ""; french: "" }> = {
  languages: {
    english: { name: "english" },
  },
};

核心诉求

我希望不需要手动传递泛型参数,让TypeScript自动推断类型并实现上述约束。我尝试过直接定义非泛型类型,但这种写法无法达到预期效果(因为索引签名允许任意字符串键,无法绑定键名与name的值):

// 此代码无效,仅用于表达需求意图
export type Languages = {
  // 允许任意字符串作为键
  readonly [TLanguageName in string]: { 
    // 期望键名确定后,name必须与键名一致
    readonly name: TLanguageName;
  };
};

// 这种写法下TypeScript不会报错,不符合需求
const fields: Languages = {
  english: { name: "french" },
};

可行的自动推断方案

直接定义非泛型类型无法实现这种“键值绑定”的约束,但可以通过泛型辅助函数让TypeScript自动推断类型,无需手动传递泛型参数:

// 定义一个辅助函数,通过泛型自动推断约束关系
const createProfile = <T extends Record<string, { name: keyof T }>>(profile: { languages: T }) => profile;

// 合法示例:TypeScript自动验证所有键名与name匹配
const validProfile = createProfile({
  languages: {
    english: { name: "english" },
    french: { name: "french" }
  }
});

// 不合法示例:TypeScript会直接报错,提示name与键名不匹配
const invalidProfile = createProfile({
  languages: {
    spanish: { name: "italian" } // 错误:类型"italian"不能赋值给类型"spanish"
  }
});

方案说明

  • 泛型T被约束为Record<string, { name: keyof T }>,意味着T中的每个键K,对应的子对象的name属性必须是K本身。
  • 通过辅助函数创建对象时,TypeScript会自动推断T的具体结构,无需手动指定泛型参数,完美解决多层结构下泛型传递的问题。
  • 如果存在多层嵌套结构,只需要在最外层的辅助函数中定义泛型约束,内部层级会自动继承推断出的类型关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:50:29