microsoft / node-api-dotnet

Advanced interoperability between .NET and JavaScript in the same process.
MIT License
426 stars 49 forks source link

Wrong typecript namespaces with class composition #267

Closed daniacedue closed 2 months ago

daniacedue commented 2 months ago

Hello,

I am trying to use class composition like this:

namespace NAOTConsoleGreet {
    [JSExport]
    public class MainEntry {
        public HumanGreet Human { get; set; } = new HumanGreet();
        public DuckGreet Duck { get; set; } = new DuckGreet();
    }
    [JSExport]
    public class HumanGreet {
        public string Greeting { get; set; } = "Hello from human!";
} }
namespace AnimalGreetings {
    [JSExport]
    public class DuckGreet {
        public string Greeting { get; set; } = "Quack!";
} }

but it generates this d.ts:

export class DuckGreet {
    constructor();
    greeting: string;
}
export class MainEntry {
    constructor();
    human: NAOTConsoleGreet.HumanGreet;
    duck: AnimalGreetings.DuckGreet;
}
export class HumanGreet {
    constructor();
    greeting: string;
}

As you can see:

Thanks in advance!

P.S: As a workaround I am using the same global namespace for all my project's classes + a script to post-process the output d.ts file (it replaces the unnecessary namespace strings with an empty one) which is laborious.

jasongin commented 2 months ago

.NET types tagged with [JSExport] are not namespaced in JavaScript/TypeScript - that is by design and follows modern JS conventions in which it is preferable to organize JS APIs by modules and not by namespaces.

On the other hand, .NET namespaces are preserved when dynamically loading pre-existing .NET assemblies (with no [JSExport] attributes), because .NET types are conventionally organized by namespace and it would not work well to reorganize them by assembly/module. There is some more explanation here about the differences between these 2 approaches, but I need to document this better.

All that said, there is clearly a bug in the generated typedefes: it should not be using those namespace prefixes when referencing other exported types. I'll fix that.