如何让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
相关产品推荐
相关产品推荐

