TScert:TypeScript 的可靠内核
TScert: A Sound Core for TypeScript

原始链接: https://github.com/cristianoc/TScert

TScert 是一个研究工具,通过机器检查证明验证 TypeScript 函数的类型安全,而不是信任 TypeScript 故意设计的不健全检查器。它仅在 Lean 验证的证明表明:对于满足其注解的输入,函数翻译到形式化演算中时,从不将操作应用于不匹配的值,也不在结果类型之外返回;它仍可能抛出或循环。一个 OCaml 生产者将表达式/变量类型作为不可信声明提出,一个不可信搜索提出证书,Lean 检查器(由定理 `checkUnitJson_safe` 支撑)对其进行验证。受信任假设包括翻译忠实性、库/宿主契约、调用者/导入和 Lean。在 v0.94 版本中,686 个工具函数中的 643 个可验证。它支持广泛的 TypeScript 子集(控制流、泛型、async/await、类等),但拒绝 `any` 和类型断言;每个不支持的形式都会附带原因和位置被拒绝。项目包括管道示例、文档和 NON-AI MIT 许可证。

黑客新闻 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 投稿 登录 TScert:TypeScript 的健全内核 (github.com/cristianoc) 8 分,由 bpierre 发布于 2 小时前 隐藏 | 过往 | 收藏 | 讨论 帮助 | 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文

TScert: a sound core for TypeScript

TScert checks that TypeScript functions are type-safe, and accepts a function only with a proof. A checker whose soundness is proved in Lean validates that proof. It never trusts the types that TypeScript or the proposing tools infer; what it does trust is listed under What acceptance means.

tscert-launch.mp4

TypeScript's type checker is deliberately unsound in places: any, type assertions, unchecked index reads and covariant arrays let programs that pass tsc still read undefined where a type says string. TScert gives a stronger answer for the code it accepts: for every input that meets its annotations, the function's translation into a formal model never applies an operation to a value it does not fit, and never returns a value outside its result type. A theorem in Lean states that guarantee, and the checker that decides acceptance is the code the theorem is about.

The checker, a turnstile with a magnifying glass

TypeScript accepts this function (under strict, which leaves noUncheckedIndexedAccess off). TScert refuses it:

export function stale(xs: string[]): string {
  const n = xs.length;
  xs.pop();
  return xs[n - 1]; // past the end after the pop: undefined at run time
}

Abridged output (offsets refer to the example file):

"status": "unverified"
reject: source expression obligation at [219,228): evidence search failed: no derivation of its return-contract claim
obligation: The available claim for xs[n - 1] is undefined | string. This return requires string.

With the result type stated honestly, string | undefined, TScert accepts it. Both versions are pipeline cases: invalid-array-last-after-pop.ts and afterPop in array-last-element.ts.

Parse, plan and elaborate are trusted on review; propose and search are proposals that may be wrong; check is proved sound and receives the certificate and the same request elaboration produced.

A front end on TypeScript's compiler API reads the source and the declarations it uses, and Lean plans its execution. An OCaml program, the producer, proposes the type of every expression and variable; its answers are claims, and none is trusted. Lean translates the function, with those types, into a small formal language (the calculus) whose execution and safety are defined in Lean. An untrusted search proposes a certificate, a derivation that the program meets its types, and the checker validates it against the same translation. The stages describe each step.

Acceptance proves, of the function's translation into the calculus, that for inputs and a heap meeting their declared types it does not get stuck and does not return a value outside its result type. It may throw or run forever. The theorem is checkUnitJson_safe. Some things are trusted rather than proved:

  • that the translation from TypeScript to the calculus is faithful (reviewed and tested, not proved);
  • that library and host functions behave as their reviewed contracts state;
  • that callers and imports meet their declared types;
  • Lean itself.

The trust surface lists every assumption, and what "verified" means states the guarantee exactly.

TScert is a research project, unfinished by design. Its benchmark is its own front end: at v0.94, 643 of the 686 functions of tools/ verify, each checked in its own unit with what it calls read at its stated signature (census of ae20a6c6, 2026-11-04). The coverage metrics and the status table give the definitions and the dated measurements.

In outline, the supported subset covers:

  • const/let, patterns, if, switch, loops including for...of and for...in, labeled blocks, throw and try/catch/finally;
  • primitives with literal types, arithmetic, comparisons, template literals, typeof, in, instanceof and strict equality;
  • object literals with spreads, records, index signatures, arrays and tuples, optional chaining, enums, and classes with fields, methods and a base class;
  • functions, closures, optional, default and rest parameters, generic functions certified for every admissible type argument, async and await of native promises;
  • declared types: aliases, interfaces, unions, intersections and library types through reviewed contracts.

any is refused, and a type assertion (e as T, e!) decides nothing. Every unsupported form is refused with a reason and a location. The fragment boundary lists what is refused and why.

TScert builds on decades of work on types and semantics, among them Appel and McAllester's indexed model for foundational proof-carrying code, Ahmed's semantics of types for mutable state, Wright and Felleisen's syntactic type soundness, Reynolds's parametricity, Abadi and Cardelli's theory of objects, semantic subtyping, JSCert, the ECMAScript specification and Lean 4. REFERENCES lists every work, with what TScert takes from it and where.

Prerequisites: Node, the pinned Lean toolchain, OCaml and Dune (the producer guide). Then:

make setup                                   # node dependencies
make build                                   # the Lean verifier and the OCaml producer
make check FILE=pipeline/examples/array-last-element.ts

make check prints the outcome and the directory holding the run's documents: the source, the parser's output, the producer's claims and the certificate.

make test     # fast checks and the controls (forged documents and claims)
make suite    # every pipeline case: source files with their expected outcome
make help     # every target

Licensed under the NON-AI MIT License: the MIT terms, with the code excluded from use in training or improving machine-learning systems and from datasets for that training, also for its derivatives.

The copyright holder reserves the rights in this repository against text and data mining, under Article 4(3) of Directive (EU) 2019/790, including for training or improving machine-learning systems; ai.txt states the same reservation in machine-readable form.

联系我们 contact @ memedata.com