设计文档
Nudo — 面向 JavaScript 的类型推断引擎。类型系统是 Abs(
shape × term × pred × conf)——类型是可计算值,携带约束并参与代数。不存在第二套 IR:dts/LSP/序列化直接消费 Abs,外延视图是单向、有损的渲染。生产分析 Abs 原生。
1. 愿景与核心思想
1.1 问题
TypeScript 的类型系统强大,但它运行在一个独立于 JavaScript 的语言中。复杂的类型级计算需要「类型体操」——条件类型、映射类型、infer、模板字面量类型——这是一套与开发者日常编写的值级 JavaScript 完全不同的编程模型。
// 开发者在值层面编写的代码(直观):
function transform(x) {
if (typeof x === "string") return x.toUpperCase();
if (typeof x === "number") return x + 1;
return null;
}
// 他们必须在类型层面编写的代码(晦涩):
type Transform<T> =
T extends string ? Uppercase<T> :
T extends number ? number :
null;
这两种表示描述的是同一个逻辑,却存在于两个互不相通的世界。当逻辑复杂时,保持它们同步既痛苦又容易出错。
1.2 核心洞察
如果值级代码本身就是类型级计算呢?
Nudo 既不像 TypeScript 那样静态分析代码,也不像测试那样用具体值运行代 码,而是用抽象值(Abs)执行代码——类型携带 shape、符号项与约束。执行本身产生类型;约束随运算传播(x>0 ⇒ x+1>1)。
传统方式: 源代码 → 静态分析 → 类型
Nudo: 源代码 + Abs → 执行 → 类型 + 约束
这不是「通过样例归纳类型」。这是抽象解释(Abstract Interpretation)——以「运行代码」这一熟悉心智模型呈现。
1.3 关键区分:具体执行 vs 符号执行
| 方式 | 输入 | 输出 | 完备性 |
|---|---|---|---|
| 单元测试 | 具体值(1、"hello") | 具体结果 | 仅覆盖测试用例 |
| Nudo | Abs(shape × term × pred) | Abs(展示时外延渲染) | 覆盖抽象集合中的所有值 |
| TypeScript | AST(不执行) | 类型 | 覆盖所有语法路径 |
2. 类型系统:Abs
2.1 Abs —— 类型系统本体
Abs 是唯一类型系统:shape × term × pred × conf。
| 分量 | 含义 |
|---|---|
| shape | 结构种类:any / unknown / prim / obj / arr / tuple / fn / brand / eff / sum / never |
| term | 值的符号身份:字面量、变量或应用(x+1) |
| pred | 相对 term 的约束:x>0、合取等 |
| conf | 置信度:exact / path / widened / partial / opaque |
any 表示「任意 JS 值」(无约束参数);unknown 表示「分析拿不到信息」。二者不同。
Abs 上的运算是代数的:单调算术、比较、leq 可赋值、谓词蕴含。nudo check 是这套代数上的 CI 门禁(金标 recall = precision = 1.0)。