Phase 6. Extern emitter
| Field | Value |
|---|---|
| MEP | MEP-72 §Phases |
| Status | NOT STARTED |
| Tracking issue | (pending) |
| Tracking PR | (pending) |
| Commit | (pending) |
Gate
TestPhase6ExternEmit in package3/typescript/emit/phase06_test.go: subtests emit_function, emit_class, emit_namespace, emit_alias, emit_skip_block, emit_capabilities_block, golden_corpus. The first six render representative items and assert the emitted Mochi source compiles via the MEP-52 parser (no syntactic errors). The seventh emits a full shim for each of the 24 fixture packages and asserts byte-equality against the golden shim.mochi files.
Lowering decisions
The emitter produces a single shim.mochi file per consumed package, written to target/ts_shims/<pkg>@<version>/shim.mochi. The file is deterministic (sorted by declaration name, with comment header recording the schema version + source-package hash). The file is .gitignored by default; the user does not normally read or hand-edit it.
File structure:
// AUTO-GENERATED by mochi pkg lock for npm:[email protected]
// schema-version: 1
// source-hash: sha512-<base64>
// === capabilities ===
// capabilities-declared: net
// sigstore-attested: true
// === extern types ===
extern type Schema<T>
extern type ZodError
extern type ParseResult<T>
// === extern fns ===
extern fn z.string(): Schema<string>
extern fn z.number(): Schema<float>
extern fn z.object<T>(shape: map<string, Schema<T>>): Schema<map<string, T>>
extern fn (s: Schema<T>) parse(input: any): ParseResult<T>
// === skip reports ===
// skip: SkipConditionalType for `infer` in z.infer<T>
// skip: SkipMappedDepth for z.deepPartial (mapped depth 3)
The emitter never emits a partial declaration: if any sub-component of an item produced a SkipReport, the entire item is recorded as skipped and absent from the emitted code. This avoids the dangling-reference problem (an extern fn referencing an unmapped type).
The extern type T declarations use Mochi's existing extern-type syntax (MEP-52 phase 12.4). The MEP-52-emitted TS for an extern type T is a TypeScript type alias type T = unknown plus an import binding back to the consumed package's source.
The emitter respects the user-set alias from import ts "<pkg>@<semver>" as <alias>: the emitted extern fn names are namespaced by the alias. Two consumers of the same package with different aliases produce two distinct shim files; the build cache shares the underlying ApiSurface and type-mapping results.
JSDoc comments are passed through as Mochi /// doc comments on the corresponding extern fn so Mochi-side documentation tooling (MEP-50) picks them up.
@deprecated JSDoc tags become a // DEPRECATED: <reason> comment + a lint warning at the call site (MEP-52 phase 12 already wires deprecation linting).
Files changed
| File | Purpose |
|---|---|
package3/typescript/emit/emitter.go | Emitter, EmitPackage, EmitItem, EmitType |
package3/typescript/emit/writer.go | deterministic-ordered Mochi source writer |
package3/typescript/emit/aliases.go | per-import alias namespacing |
package3/typescript/emit/jsdoc.go | JSDoc → Mochi doc-comment pass-through |
package3/typescript/emit/phase06_test.go | TestPhase6ExternEmit sentinel |
package3/typescript/emit/testdata/golden/*.mochi | per-package golden shim files |
Test set
7 subtests as listed in the Gate section.
Cross-references
- MEP-72 §4 Surface syntax — the import-ts syntax this emitter binds against.
- MEP-74 phase 7 extern emit — the sister Go-side extern emitter.