Skip to content

feat(cli): emit faithful TypeScript module declarations - #1527

Open
oxura wants to merge 1 commit into
bendlang:mainfrom
oxura:fix/issue-1144-module-declarations-20261012
Open

oxura wants to merge 1 commit into
bendlang:mainfrom
oxura:fix/issue-1144-module-declarations-20261012

Conversation

@oxura

@oxura oxura commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #1144.

-o core.mjs now emits core.d.mts from checked telescopes and constructor fields. Runtime and declaration export filtering share js_exports; the module retains its default object, while declaration named exports are type-only. Native Nat follows current main's number ABI (#1506), not the older BigInt example in the issue.

The declarations preserve recursive tagged values, generic datatype fields, arrays, callback shapes and every prefix of a partially applied exported function. Private identifiers are encoded separately from public type names, including reserved names. Erased/template, kind-returning and unresolved type-family signatures remain runtime exports but are omitted from declarations; an unmapped concrete type reports the def and writes neither file. No any approximation.

Both generated paths use the existing input/directory guard before either is written. The separate existing hard-link issue #1495 / PR #1496 is not claimed fixed here.

Real behavior proof

Linux x86_64; Bun CLI 1.3.13, Node v22.23.1, TypeScript 5.9.3 installed as isolated verification tooling, not a repository dependency.

Before, the real typed consumer failed with exit 2 / TS7016 (no declaration for core.mjs). After actual CLI emission:

bun bend2/main.ts core.bend -o core.mjs
node path/to/typescript/bin/tsc --strict --module nodenext --target esnext good.mts
node good.mjs

Four actual TypeScript-compiled Node hosts passed:

  • Slot/List consumer: true 9.
  • Recursive Tree, callback and full/partial/zero-prefix calls: 10 10 9 9 9 9.
  • Reserved type name class and helper-like type BendFn: 7 8.
  • Native array update: [8,5].

Negative TypeScript consumers are rejected with TS2614 (invented named value export), TS2345 (invalid direct/partial call), TS2322 (malformed constructor field) and TS2339 (intentionally omitted erased signature). A concrete indexed type not mapped by this emitter exits 1 naming identity; neither output is created.

Regression checks

  • Permanent tests/io/module_declaration_safety.bend and its real JS effect invoke the actual CLI against a derived-sidecar input symlink and directory. Before: prints 1; after: 0, source preserved and no partial module output.
  • 20 real existing module/FFI/closure/marshal CLI cases matched their checked-in stdout and exit statuses.
  • bun gates/repo.ts: PASS: 54 / 54.
  • README updated. No parser/theory/checker, GUIDE, CHANGELOG, gate or cap edits.

Limits

No remote mini-cluster/macOS execution. Full dependent type semantics cannot be represented by TypeScript; only faithfully mapped signatures are declared, following the omission/error policy above. Static host checks were exercised with TypeScript 5.9.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bend -o <out>.mjs: also write the type declaration

1 participant