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

在TypeScript类型系统实现带类型简易Lisp的map功能遇阻求助

在TypeScript类型系统中实现带类型的简易Lisp:map功能的上下文扩展问题

我正尝试受JSON Logic启发,在TypeScript类型系统中实现一个带类型的简易Lisp,现有实现如下:

/**
 * 给定上下文对象C,该类型允许你构造可引用上下文并对其中数据执行操作的表达式。
 *
 * 以下未展示的类型定义:
 *   JSONData: JSON非对象类型的简单类型表示
 *   JSONPath: 终端路径的联合类型(即给定JSON对象中的路径)
 *   JSONPathValueType: JSON对象中给定路径对应的值类型
 */

type Expr<A extends JSONData, C extends JSONData> = A extends number
  ?
      | number
      | Ref<number, C>
      | ['+', ...Expr<number, C>[]]
      | ['first', Expr<number[], C>]
  : A extends JSONObject
  ? JSONObject | Ref<JSONObject, C>
  : A extends JSONArray<infer T>
  ?
      | T[]
      | Ref<T[], C>
      | ['map', Expr<JSONArray, C>, Expr<T, C>]
  : never;


type Ref<T, C extends JSONData> = {
  [P in JSONPath<C>]: JSONPathValueType<P, C> extends T ? `$.${P}` : never;
}[JSONPath<C>];

基于上述定义,以下表达式均合法:

type Context = { foo: 1; bar: { baz: 2; bin: [5]; buz: [{ fiz: 3 }] } };
type SampleNumberExpr = Expr<number, Context>;

const two: SampleNumberExpr = ['+', 1, 1];
const three: SampleNumberExpr = ['+', '$.foo', '$.bar.baz'];
const four: SampleNumberExpr = ['first', [4, 5, 6]];
const five: SampleNumberExpr = ['+', 1, ['first', [4, 5, 6]]];
const six: SampleNumberExpr = ['+', '$.foo', ['first', '$.bar.bin']];

但在实现和使用map功能时遇到了问题。理想情况下,我希望能在表达式中用Ref的$.item语法访问列表中的每个元素,例如:

const doesNotWork: SampleNumberExpr = 
  ['first', ['map', '$.bar.buz', ['+', '$.item.fiz', 1]]]

但所有尝试均触发类型错误,或出现Type instantiation is excessively deep and possibly infinite.的编译错误。

我卡在了为map功能创建新上下文这一步——需要让$.item键匹配输入数组Expr的元素类型。我直觉上认为这个方案可行,希望得到帮助确认并解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:10:40