如何创建仅允许单个字段的TypeScript Record泛型类型?
如何创建仅含单个字段的TypeScript Record变体
要实现一个强制仅存在单个字段的Record<K, V>变体,我们可以通过交叉类型结合索引签名来限制多余字段的存在:
type SingleFieldRecord<K extends PropertyKey, V> = { [P in K]: V; } & { [Q in PropertyKey]?: never; };
原理说明
- 第一个部分
{ [P in K]: V }:定义所有K类型的键对应V类型的值,和普通Record行为一致。 - 第二个部分
{ [Q in PropertyKey]?: never }:定义所有属性(包括K之外的类型)的可选类型为never,意味着任何额外字段都无法被赋值(never类型没有合法值)。 - 两者交叉后,若对象存在多个
K类型的键,这些键的类型会合并为V & never(即never),导致赋值时报错;仅当对象只有一个K类型的键时,该键的类型保持为V,符合要求。
基础测试验证
let test: SingleFieldRecord<string, number>; test = { 'some.field': 1 }; // ✅ 合法,仅单个字段 test = { 'another.random.field': 1, 'extra.field': 2 }; // ❌ 错误:多余字段的类型为never,无法赋值
应用到你的操作符场景
将SingleFieldRecord替换原有的索引签名,即可限制每个操作符仅能对应单个字段:
type SingleFieldRecord<K extends PropertyKey, V> = { [P in K]: V; } & { [Q in PropertyKey]?: never; }; type Operator = | { $stringIn: SingleFieldRecord<string, string[]>; } | { $numericGE: SingleFieldRecord<string, number>; }; // ... // 示例 const op: Operator = { $numericGE: { 'customer.age': 18, // 'customer.height': 6 // ❌ 此处会报错,禁止多余字段 } }
这样就能满足API要求,确保每个操作符对象仅包含单个目标字段。
内容的提问来源于stack exchange,提问作者joeveiga
相关产品推荐
相关产品推荐

