-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Generate d.ts file from JSExport attributes #74233
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsBackground and motivationJSExport Attribute can make .NET static methods accessible to JavaScript side. However, access to such methods requires the correct namespace, class name, and method name, and may result in access to invalid objects. By outputting d.ts when generating JavaScript Interop source, it is possible to type exported objects, which will improve the development experience. API Proposaldotnet.d.ts declare type APIType = {
runMain: (mainAssemblyName: string, args: string[]) => Promise<number>;
runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise<number>;
setEnvironmentVariable: (name: string, value: string) => void;
- getAssemblyExports(assemblyName: string): Promise<any>;
+ getAssemblyExports<T = any>(assemblyName: string): Promise<T>; dotnet.g.d.ts import "@microsoft/dotnet-runtime";
declare module "@microsoft/dotnet-runtime" {
interface AssemblyExports {
MyClass: {
Greeting: () => void;
}
}
} API Usagemain.mts import { dotnet, AssemblyExports } from "@microsoft/dotnet-runtime";
const { getAssemblyExports } = await dotnet
.withDiagnosticTracing(false)
.create();
const config = getConfig();
const exports = await getAssemblyExports<AssemblyExports>(config.mainAssemblyName);
const text = exports.MyClass.Greeting();
console.log(text); wasmconsole.csproj <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<WasmMainJSPath>main.mjs</WasmMainJSPath>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<JSInteropTypeDefinitionOutputDir>./types</JSInteropTypeDefinitionOutputDir>
</PropertyGroup>
<ItemGroup>
<CompilerVisibleProperty Include="JSInteropTypeDefinitionOutputDir" />
</ItemGroup>
</Project>
Alternative DesignsPoC: https://github.com/yamachu/NetWebAssemblyTSTypeGenerator Risks
|
I/O in a generator is unsupported, so this needs to wait for dotnet/roslyn#57608 to be doable in a supported fashion. |
Does this usage work as is ? const exports:AssemblyExports = await getAssemblyExports(config.mainAssemblyName); I'm not sure that the TypeScript definitions generator need to be part of the runtime. |
On the flipside. Are there any way or plan to generate C# wrapper over javascript package from its So we could write C# wasm with any existing npm package that provide |
The JS interop only supports static functions and limited set of marshaled argument types. |
@pavelsavara Isn't all the type of js can be reference in C# as And then we make a class as a wrapper of Could you please give me an example of what impossible to generate right now? |
Yes, you can generate wrapper class around the JSObject. Let's say you want to have WebSocket instance and you would generate C# class for it. Which part of the interop pipeline would create the instance of WebSocket C# proxy ? Now let's say that we have TypeScript definition of WebSocket.send(). You can see that there are multiple types of the Even if somebody would really want to try to do it, I still think that it's not something we need to do in the runtime repo. |
@pavelsavara I kind of thinking that this feature should be native to wasm and/or blazor build system. And it was not ideal that we could not decouple wasm and blazor from runtime repo It would be very convenient for dotnet wasm compiler to able to import existing package in npm into C# so we could utilize every critical 3rd party package in the web world that will only written as npm package |
Also while it would impractical for general type in JavaScript. I think we could scope the possibility into only class that have |
@pavelsavara Should I made separate issue about codegen for C# side or would you consider this feature as the same interoperability system between |
Let's keep the discussion in single place for now. |
Perhaps making |
It definitely decrease barrier but being |
Is there strong reason why we could not go with the hack described at the top of dotnet/roslyn#57608 until they fix it ? That is for generating |
On topic of generating C# from .d.ts, I assume we are not going to implement TypeScript parser in C# in order to be able to plug it into the Roslyn process, right ? That said, I see one benefit of triggering the C# code gen in Roslyn via attribute. The ability to discover it in the code. What are the other benefits of Roslyn generator based on external metadata ? Alternatively I could imagine pre-Build MSBuild target which would run generator based on Any other ideas how this could be implemented ? |
I expect that we could just run TS language server in the project, make it like TS/JS normal project. Then communicate with it by some means, the generator will act like another IDE to glean the shallow namespace and class we can import from typescript Then when we But that might be later. For the start we might just use |
"normal js project" could be NextJS, ReactApp, Angular, webpack, just plain TS and anything in between.
Are you planning to start working on it @Thaina ? What kind of support do you need ? |
If possible I think in the end this system would be general ts->cs generator that don't really care about framework. The use case is just that, it let us access class, property, and function available in typescript definition, and the framework specific feature might be skipped if it not really in the possible pattern of C# But for the start I think we might focus on pure wasm project that just written in raw html and include javascript, the one that generated from IMO the one thing that would
I have start investigate the language server's client capability, I try to find the easiest way to have C# communicate with TS. But for now I want solid plan and clear goal of this feature first, so I don't waste my time race against what other would do. And I would like to wait for complete wrapper of |
@pavelsavara The hack can fail at any time and might not regenerate the file when you expect. I personally see the workaround for use in a "we need this for a high-priority business need", not a nice-to-have feature, especially since if it behaves weirdly, we'll get bugs about the behavior filed and we won't be able to fix them as we're actively doing something the compiler team has told us not to do. |
Background and motivation
JSExport Attribute can make .NET static methods accessible to JavaScript side.
However, access to such methods requires the correct namespace, class name, and method name, and may result in access to invalid objects.
By outputting d.ts when generating JavaScript Interop source, it is possible to type exported objects, which will improve the development experience.
API Proposal
dotnet.d.ts
dotnet.g.d.ts
API Usage
main.mts
wasmconsole.csproj
Alternative Designs
PoC: https://github.com/yamachu/NetWebAssemblyTSTypeGenerator
Risks
The text was updated successfully, but these errors were encountered: