emscripten-core / emscripten-core/emscripten

Using --embind-emit-tsd should define auxiliary Webassembly-module members

Open
#20,296 5 comments 3 reactions 1 assignee Claimed by @brendandahl View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

On the latest release of EMSDK, `3.1.46`, I can now use the `--embind-emit-tsd` flag to generate embind TS definitions for my webassembly modules. However, naively switching to this causes some TS compiler complaints about missing members and functions, as our hand-written `.d.ts` files included some subset of the [auxiliary `EmscriptenModule` definitions](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/emscripten/index.d.ts#L43) (basically whatever we were actually using and needed). For our projects we used a pattern looking like this:

```Typescript
export interface WebassemblyModule {
HEAPU8: Uint8Array;
_malloc(size: number): number;
_free(ptr: number): void;
// Other auxiliary stuff might be defined here
}

export interface MyModule extends WebassemblyModule {
myBindingsGoHere(): void;
}

declare function MyModule(options?: {
locateFile(filename: string): string;
}): Promise;

export default MyModule;
```

In concept this can be worked around without too much effort, by emitting the embinding definitions to something like `wasm.ts`, then hard-coding a TS definition file like this.

```Typescript
import {
type MainModule
} from "./wasm.js";

export interface WebassemblyModule {
HEAPU8: Uint8Array;
_malloc(size: number): number;
_free(ptr: number): void;
}

export type MyRealModule = MainModule & WebassemblyModule;

declare function MyRealModule(options?: {
locateFile(filename: string): string;
}): Promise;

export default MyRealModule;

export * from "./wasm.js";
```

Of course the downside to this is that it still has to be manually maintained, and it adds complication to builds.

If it's not a huge lift, it would be nice to include auxiliary stuff, such as things exposed by the `EXPORTED_FUNCTIONS` flag & whatever is always there, so users don't have to manually add them. That way, nothing needs to be manually maintained, and the `d.ts` file advertises (closer to) everything accessible on the module object.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.