Skip to main content

Phase 6. Extern emitter

FieldValue
MEPMEP-72 §Phases
StatusNOT 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

FilePurpose
package3/typescript/emit/emitter.goEmitter, EmitPackage, EmitItem, EmitType
package3/typescript/emit/writer.godeterministic-ordered Mochi source writer
package3/typescript/emit/aliases.goper-import alias namespacing
package3/typescript/emit/jsdoc.goJSDoc → Mochi doc-comment pass-through
package3/typescript/emit/phase06_test.goTestPhase6ExternEmit sentinel
package3/typescript/emit/testdata/golden/*.mochiper-package golden shim files

Test set

7 subtests as listed in the Gate section.

Cross-references