gjsify / ts-for-gir

TypeScript type definition generator for GObject introspection interfaces
https://gjsify.org/pages/projects
Apache License 2.0
237 stars 18 forks source link

Generate ambient definitions #103

Closed CharlieQLe closed 1 year ago

CharlieQLe commented 1 year ago

Currently, ts-for-gir doesn't have ambient definitions to link generated definitions to the "gi://..." import syntax. This PR generates the ambient definitions necessary, which should allow ts-for-gir to be used for an application that packs JS files into gresources.

Trying to generate ambient definitions for all of the GIRs in the vala submodule currently results in a heap limit error, but it works fine with the GIR files on my own system.

EDIT: This does mean that modules with multiple versions should only have a single type generated, since the ambient definitions generate an unversioned and a versioned ambient module for each GI module, regardless of what versions exist. I can't really think of a solution to this that doesn't involve manually deleting the duplicate ambient modules if one needs two different versions of a GI module.

JumpLink commented 1 year ago

Hi @CharlieQLe, thank you very much for contribution!

Why did you create an extra file for this instead of append this to the end of<moduleName>-<version>.d.ts?

In your separate file, you also need to import the namespace first, e.g. like this:

import Gio from './Gio-2.0.js' // <- Add this

declare module "gi://Gio" {
  export default Gio;
}

declare module "gi://Gio?version=2.0" {
  export default Gio;
}

Alternatively, the module declarations could also all be append to the index.d.ts as we do this for the imports.gi.<moduleName> imports.


But forgot both, a bigger problem is, that Typescript does not recognize the ambient module import in URL format, a solution for this seems to be using path aliases in the tsconfig file:

{
  "compilerOptions": {   
    "paths": {
      "gi://Gio?version=2.0": ["./@types/Gjs/Gio-2.0.d.ts"],
      "gi://Gio": ["./@types/Gjs/Gio-2.0.d.ts"],
      "gi://GLib?version=2.0":  ["./@types/Gjs/GLib-2.0.d.ts"],
      "gi://GLib": ["./@types/Gjs/GLib-2.0.d.ts"],
      "gi://GObject?version=2.0": ["./@types/Gjs/GObject-2.0.d.ts"],
      "gi://GObject": ["./@types/Gjs/GObject-2.0.d.ts"],
    },
  }
}

Therefore my suggestion would be to generate a tsconfig.alias.json that looks like the one suggested above. For this the CLI option should also be renamed and the ambient import can then be removed unless you somehow get it to work differently.

CharlieQLe commented 1 year ago

Why did you create an extra file for this instead of append this to the end of -.d.ts?

It was a quick proof of concept, if it is preferable to place it in the index file, then I can do that.

In your separate file, you also need to import the namespace first, e.g. like this:

That does work! I didn't think of that, so I can adjust the template to reflect this change.

But forgot both, a bigger problem is, that Typescript does not recognize the ambient module import in URL format, a solution for this seems to be using path aliases in the tsconfig file:

I made an adjustment in the tsconfig.json file already that works properly with the ambient definitions. But as you mentioned, generating a tsconfig.alias.json file seems to be a cleaner solution.

How do you think we should handle the possibility of multiple different versions? If one generates ambient definitions- or path aliases- for both GTK3 and GTK4 for example, then it could present a problem if multiple path aliases show up.

EDIT: Currently working on the tsconfig.alias.json implementation and the generated paths only work when moved into tsconfig.json. To be sure, would this be the intended behavior? If so, I think that generating ambient definitions in a singular file may be better, since it doesn't involve moving the aliases to tsconfig.json. On my machine, tsconfig.alias.json doesn't seem to do anything.

CharlieQLe commented 1 year ago

Now it generates tsconfig.alias.json in the root directory of the project. To ensure that nothing goes wrong when extending from tsconfig.alias.json, baseUrl and includes has already been set.

JumpLink commented 1 year ago

Trying to generate ambient definitions for all of the GIRs in the vala submodule currently results in a heap limit error, but it works fine with the GIR files on my own system.

Yea, you need to run this with NODE_OPTIONS=--max_old_space_size=9216 as this requires a lot of memory, but it is enough if this passes in the CI.

CharlieQLe commented 1 year ago

All of the comments should be addressed, everything should be good.

JumpLink commented 1 year ago

@CharlieQLe Thank you very much! I will merge this as soon as possible. Do you still like to fix the conflicts? Otherwise I can do it myself tomorrow. I have changed useNamespace to noNamespace and made the use of namespaces the default.

CharlieQLe commented 1 year ago

Merged from main to fix the conflicts.

CharlieQLe commented 1 year ago

Fixed dependencies and removed leftover ambient files. Also renamed the example from ambient to alias to reflect what it actually does.

JumpLink commented 1 year ago

@CharlieQLe Thank you!

JumpLink commented 1 year ago

@CharlieQLe I am currently working on support to generate NPM packages in #106 and with my latest changes I got ambient modules to working as you originally wanted to contribute it. The problem why I couldn't get it to work before was that no normal imports work in ambient modules.

I hope to be finished with my PR soon.