Attempt at getting .d.ts files in meteor packages to be usefull

I was looking for a way to get d.ts files in meteor packages to be usefull in the projects using those packages.

I took a look at the typescript package came up with this idea:

Plugin.registerCompiler({
  extensions: ["ts", "tsx"],
}, function () {
  return new TypeScriptCompiler({
    react: true,
    typescript: true,
  }, (babelOptions, file) => {
    if (file.hmrAvailable() && ReactFastRefresh.babelPlugin) {
      babelOptions.plugins = babelOptions.plugins || [];
      babelOptions.plugins.push(ReactFastRefresh.babelPlugin);
    }
  });
});


class TypeScriptCompiler extends BabelCompiler {
  processFilesForTarget(inputFiles) {
    return super.processFilesForTarget(inputFiles
      .map(file => { //This map is my attempt at copying the d.ts files. Everything else is unchanged
        if (file.getPathInPackage().endsWith(".d.ts") && !file.getPathInPackage().startsWith("node_modules")) {
          const pathInPackage = file.getPathInPackage()
          const pathBits = pathInPackage.split('/')
          const fileName = pathBits[pathBits.length - 1] // there should probably be a better way to get the file name !?
          const packageName = file.getPackageName()
          const sourcePath = file._resourceSlot.packageSourceBatch.sourceRoot + '/' + pathInPackage
          const destinationPath = file._resourceSlot.packageSourceBatch.processor.sourceRoot + '/node_modules/meteor/' + packageName + '/' + fileName
          console.log(sourcePath + ' -> ' + destinationPath )
          //  /Users/jan-michaelpilgenroeder/Code/meteor-packages/sdui-table/imports/ui/MeteorDataAutoTable.d.ts -> /Users/jan-michaelpilgenroeder/Code/sdui-dev/node_modules/meteor/janmp:sdui-table/MeteorDataAutoTable.d.ts
          //  /Users/jan-michaelpilgenroeder/Code/meteor-packages/sdui-table/imports/ui/MeteorDataAutoTable.d.ts -> /Users/jan-michaelpilgenroeder/Code/sdui-dev/node_modules/meteor/janmp:sdui-table/MeteorDataAutoTable.d.ts
          
          // the paths look good for my local packages (this should probably fail on windows though and I have not tried this with atmosphere packages)
          // the idea was to use fs.copyFile now, but I can't get it imported or required
        }
        return file;
      })
      .filter(
      // TypeScript .d.ts declaration files look like .ts files, but it's
      // important that we do not compile them using the TypeScript
      // compiler, as it will fail with a cryptic error message.
      file => ! file.getPathInPackage().endsWith(".d.ts")
    ));
  }
}
5 Likes

Great work!

There was some previous discussion around whether or not it was a good idea to modify node_modules or not. It’s definitely nice because it’s a zero configuration solution, but it does kind of feel like npm should be the only thing updating those files.

Another option could be to have a typings or .meteor/local/typings and the default tsconfig.json could reference that directory for Meteor projects.

The problem ist that I have not figured out yet how to actually do the copying. I can’t require or import fs in that file.

What happens when you try to require or import the fs module?

With import (first line and top level of file):

   
   While loading plugin `compile-typescript` from package `janmp:typescript`:
   packages/compile-typescript_plugin.js:16: 'import' and 'export' may only appear at the top level. (16:0)

with require:

   While loading plugin `compile-typescript` from package `janmp:typescript`:
   packages/compile-typescript_plugin.js:16:10: require is not defined

here is the repo GitHub - JanMP/typescript

Hate to dredge up and old thread like this but I think this is a super important issue that needs a solution.

Did anyone ever get anywhere with this?

No progress that I’ve seen.

I also think this would need to be driven from Meteor/Tiny because of two reasons:

  1. Companies like ours with a shipping product will have already solved the typings problem by a combination of definitelytyped imports and custom written typings
  2. Meteor Isobuild is a very hard to understand huge piece of poorly documented code (no blame intended, that is natural based on history)

So the incentives for the community to pick up this work aren’t really there…

The problem with both of these things is that they suffer from the fact that the code isn’t the single source of truth from which the declarations are generated. The type declarations have to be hand written and updated manually which is time consuming and error prone. Personally this is a completely unacceptable solution and one of the things that is a deciding factor for me at the moment when starting a new project whether to use Meteor. If the project requires typescript it’s probably going to be written in Next because I refuse to waste my time writing types by hand.

Also, I’m not sure why this precludes that the Meteor core team has to solve this problem. Honestly this would be nice, and I’d love to hear if they are working on this, but I don’t think that it’s the only possible route that can be taken.

I think you underestimate this community. It’s been innovating outside of the core team and creating solutions for these types of problems since Meteor was in beta.

That being said, a zero config solution as part of Meteor’s core that generates proper types for packages written in TypeScript would be quite innovative since this functionality does not exist in any other part of the ecosystem.