elringus / bootsharp

Compile C# solution into single-file ES module with auto-generated JavaScript bindings and type definitions

Home Page:https://bootsharp.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeScript declarations for IJSObjectReference

Aragas opened this issue · comments

Anything that uses IJSObjectReference is set as any in the declaration files.
We could introduce an optional attribute JSObjectInterface that would add the necessary metadata for the declarations generator to expose the type correctly.

public sealed class JSObjectInterfaceAttribute : Attribute
{
    public JSInterfaceAttribute (Type type) { }
}

public interface IMyInterface
{
    void Method (string str);
}

public class Container
{
    [JSInterface(typeof(IMyInterface))]
    public IJSObjectReference Prop { get; set }

    public void Test ([param: JSObjectInterface(typeof(IMyInterface))] IJSObjectReference @param) { }
}

So we could have TS declarations in the following format

export interface IMyInterface {
    Method(str: string): void;
}

Another way would be to introduce generic interfaces that implement IJSObjectReference, but there are a lot of flavors, like IJSUnmarshalledObjectReference, IJSInProcessObjectReference, so while it adds some type safety for C#, the maintenance of those higher interfaces might be very costly.

Not sure what's the point in describing an existing JS/TS type in C# and generating its declaration. Why not just emit the type name instead of any?

We're describing what the C# code expects to be passed as an arguement, the minimally required methods that C# can call.
Basically a helping hand for TS, because otherwise they won't know what to implement

Iirc, C# object references are wrapped in JS with a concrete type; or you want to unwrap them under the hood? Anyway, I really don't want to complicate this stuff too much, especially given we'll have to switch to the new interop at some point.

Well, I forgot that we need to explicitly call createObjectReference for the object we pass to WASM, this complicates the code generation a lot.
This is a pretty unpleasant issue, because the TS generations are incomplete with any and I can't expose them directly. Seems that it will be easier to wrap them in a higher level abstraction and expose that instead