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

如何让TypeScript自动推断对象键名并约束值类型?

问题

我有一个以string为键的对象,但不希望键类型是宽泛的string,而是对象的具体键名,同时还要约束对象值的类型遵循规则。示例代码如下:

type ObjectValueType = {
  checked: boolean;
  fields: Path<Camera>[];
};

type ObjectType = Record<string, ObjectValueType>;

const config: ObjectType = {
  camera_stream_endpoint: {
    checked: false,
    fields: ['camera_stream_endpoint'],
  },
  layout_image: {
    checked: false,
    fields: ['layout_image'],
  },
};

上述代码中,ObjectType的键为string,值为ObjectValueType。我希望键类型是对象的具体键名(比如camera_stream_endpoint、layout_image等)而非宽泛的string,且不想手动创建键名联合类型(因为对象包含大量键),希望TypeScript自动推断这些键名。

我曾尝试使用as const断言:

const config = {
  camera_stream_endpoint: {
    checked: false,
    fields: ['camera_stream_endpoint'],
  },
  layout_image: {
    checked: false,
    fields: ['layout_image'],
  },
} as const;

这样能实现键名的正确推断,但值的类型不再受约束——比如fields本应符合Path<Camera>类型,现在输入错误值TypeScript也不会报错。

我希望同时实现:让TypeScript自动推断对象的键名,同时确保对象值符合指定的类型定义,这是否可行?

解决方案

可行,你可以通过泛型函数来实现这个需求:既让TypeScript自动推断对象的具体键名,同时严格约束值的类型符合ObjectValueType。

具体实现代码如下:

// 假设Path<Camera>是已定义的类型,示例定义如下:
type Camera = {
  camera_stream_endpoint: string;
  layout_image: string;
};
type Path<T> = keyof T;

type ObjectValueType = {
  checked: boolean;
  fields: Path<Camera>[];
};

// 创建泛型函数,约束值类型并自动推断键名
const createConfig = <K extends string>(config: Record<K, ObjectValueType>) => config;

// 使用函数创建对象,键名会被自动推断为具体联合类型,值也会受严格约束
const config = createConfig({
  camera_stream_endpoint: {
    checked: false,
    fields: ['camera_stream_endpoint'], // 符合Path<Camera>,无报错
  },
  layout_image: {
    checked: false,
    fields: ['layout_image'], // 符合Path<Camera>,无报错
  },
  // 以下代码会触发报错:'wrong_key'不属于Path<Camera>
  // wrong_key: {
  //   checked: true,
  //   fields: ['wrong_key']
  // }
});

// 此时config的类型为:
// {
//   camera_stream_endpoint: ObjectValueType;
//   layout_image: ObjectValueType;
// }
// 键名是具体的联合类型"camera_stream_endpoint" | "layout_image",而非宽泛的string

原理说明

  • 泛型函数createConfig的泛型参数K会自动推断为传入对象的所有键名的联合类型,无需手动定义键名集合。
  • 参数config被约束为Record<K, ObjectValueType>,确保每个键对应的值都严格符合ObjectValueType的类型规则,一旦值不符合要求(比如fields传入非法值),TypeScript会直接抛出类型错误。
  • 函数返回原对象,最终得到的config变量既保留了具体的键名类型,又保证了值的类型正确性。

内容的提问来源于stack exchange,提问作者Nyi Nyi Hmue Aung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:35:09