I have some Emscripten binding code (a self-contained, trivial example of which is shown below) that converts my C++ status_t return-value class into a boolean that JavaScript code can deal with efficiently. (i.e. a status_t representing an error condition is converted to JavaScript-false, while a status_t representing success is converted to JavaScript-true)
This works great when compiling the code to JavaScript, but when I try to compile the code to TypeScript (using emscripten’s --emit-tsd option, it errors out with the error Error: Missing primitive type to TS type for 'status_t'.
Is there some way to make this work when generating TypeScript bindings, in a way that is similar to how it works for JavaScript bindings, or am I just out of luck here?
// Works great to generate JavaScript bindings:
// emcc -lembind -sEXPORTED_RUNTIME_METHODS=ccall,cwrap -sWASM_BIGINT -sMODULARIZE=1 -sEXPORT_ES6=1 -sEXPORT_NAME="CPPBindings" -sENVIRONMENT=web -lembind -std=c++17 typescript_status_t_binding_problem.cpp -o output_bindings.js
// Doesn't work to generate TypeScript bindings ("Error: Missing primitive type to TS type for 'status_t'")
// emcc -lembind -sEXPORTED_RUNTIME_METHODS=ccall,cwrap -sWASM_BIGINT -sMODULARIZE=1 -sEXPORT_ES6=1 -sEXPORT_NAME="CPPBindings" -sENVIRONMENT=web -lembind -std=c++17 typescript_status_t_binding_problem.cpp --emit-tsd output_bindings.d.ts
#include <emscripten/bind.h>
#include <emscripten/wire.h>
using namespace emscripten;
class status_t
{
public:
status_t() : _errStr(NULL) {/* empty */}
status_t(const char * errStr) : _errStr(errStr) {/* empty */}
bool IsOK() const {return (_errStr == NULL);}
bool IsError() const {return (_errStr != NULL);}
const char * GetErrorString() const {return _errStr;}
private:
const char * _errStr;
};
// Tell embind how to convert status_t <-> JavaScript bool
template <> struct internal::BindingType<status_t>
{
using WireType = bool;
static WireType toWireType(status_t s, rvp::default_tag)
{
if (s.IsOK()) return true;
else return false;
}
static status_t fromWireType(WireType v) {return v ? status_t() : status_t("Error");}
};
EMSCRIPTEN_BINDINGS(status_t)
{
internal::_embind_register_bool(internal::TypeID<status_t>::get(), "status_t", true, false);
}
class SomeExampleClass
{
public:
SomeExampleClass() {/* empty */}
status_t DoSomething() {return status_t();}
status_t EpicFail() {return status_t("epic fail!");}
};
EMSCRIPTEN_BINDINGS(SomeExampleClass)
{
class_<SomeExampleClass>("SomeExampleClass")
.constructor<>()
.function("DoSomething", &SomeExampleClass::DoSomething)
.function("EpicFail", &SomeExampleClass::EpicFail);
}



