TypeScript递归表达式定义错误:Rule类型缺属性如何解决?
错误原因及解决办法
错误原因
你用Record<Operator, [Operand, Operand]>定义Rule类型的方式完全不符合需求:
- Record的强制全键特性:
Record<K, T>会生成一个要求所有K类型的键必须同时存在的对象类型。比如如果Operator是'>' | '<' | '&&',那Record要求你的规则对象必须同时拥有>、<、&&三个键,但你的示例(如rule1)只包含一个键,类型直接不匹配。 - 宽泛的Operator类型导致错误推断:如果你的
Operator定义成了string而非精确的字面量联合类型,Record<string, ...>会被TypeScript理解为需要包含所有可能的字符串键——包括它识别的关键字(如var)、操作符(如===)等,这显然不可能实现,因此抛出“缺少var、===等属性”的错误。
解决办法
你需要定义的是**单个操作符对应一组操作数(支持嵌套规则)**的对象类型,而非要求全键的Record类型。可以通过映射类型的索引访问来实现:
1. 精确定义基础类型
// 操作数:根据实际需求扩展(比如支持字符串、布尔值等) type Operand = number | string | boolean; // 支持的操作符:用字面量联合类型严格限定,避免宽泛的string type Operator = '>' | '<' | '&&' | '||' | '===';
2. 定义正确的Rule类型
通过映射类型生成单个键值对的联合类型,每个Rule实例只需包含一个Operator键,值为对应操作数数组(支持嵌套Rule):
type Rule = { [K in Operator]: [Operand | Rule, Operand | Rule] }[Operator];
3. 验证示例
现在你的示例规则可以正确通过类型检查:
const rule1: Rule = { '>': [3, 2] }; // 符合类型 const rule2: Rule = { '&&': [ { '>': [3, 1] }, { '<': [1, 3] } ] }; // 嵌套规则也符合类型
扩展:支持单目操作符(如!)
如果需要支持单目操作,可以拆分Operator并扩展Rule类型:
type UnaryOperator = '!'; type BinaryOperator = '>' | '<' | '&&' | '||' | '==='; type Operator = UnaryOperator | BinaryOperator; type Rule = // 单目操作:单个操作数/规则 | { [K in UnaryOperator]: [Operand | Rule] }[UnaryOperator] // 双目操作:两个操作数/规则 | { [K in BinaryOperator]: [Operand | Rule, Operand | Rule] }[BinaryOperator]; const rule3: Rule = { '!': [true] }; // 单目操作符合类型
内容的提问来源于stack exchange,提问作者brospars
相关产品推荐
相关产品推荐

