11

I'm working on a JavaScript transpiler that apart from other things will also replace certain functions and variables upon build.

For example the following file (./src/my-module.js):

defineModule("MyModule", function(exports) {
  return exports;
});

Will be copied and converted to (./build/my-module.js):

(function(global, factory) {
  "use strict";
  if (typeof exports !== "undefined" && typeof module !== "undefined") module.exports.MyModule = factory(exports.MyModule || {});
  else factory(global.MyModule = {});
})(this, function(exports) {
  return exports;
});

Some of these functions could also return a result. In that case I would like to be able to declare the types of the parameters and the result of the function without using require. Is it possible to have a global .d.ts definition in VSCode?

So far, all I've done is add the functions to the global variable of eslint so as to not have errors.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • I am not sure if I understood correctly. Is this a Typescript project? If yes, what about adding the types to the `paths` config in `tsconfig.json`? Let me know if this is what you are looking for, so I will prepare an answer with details later. – saulotoledo Jul 21 '19 at 14:06
  • So you are trying to declare the type of `defineModule` without defining the function (because it will only be inlined by the transpiler, there is no actual callable function anywhere)? – Bergi Jul 21 '19 at 14:19
  • @saulotoledo, I'm working on a transpiler, which means that Im working on a project (completely besides the point if it is JavaScript or TypeScript) that will alter the contents of JavaScript files. It would be ideal to have the declarations in a global `.d.ts` file somwhere that I can reference from all my projects without the need of a `require` statement. – nick zoum Jul 21 '19 at 14:20

2 Answers2

7

You can specify your own TypeScript folder path in your settings.json where you can specify your own lib.*.d.ts files using the typescript.tsdk option.

{
  "typescript.tsdk": "node_modules/typescript/lib"
}
mootrichard
  • 3,581
  • 13
  • 25
  • While I followed your instructions and put my `.d.ts` with the other `.d.ts` files of typescript, VSCode still says the type of `defineModule` is `any`. Also, VSCode was trying to get the `node_modules/typescript/lib` using a path relative to the current workspace instead of the `Roaming/npm/node_modules`. I have temporarily fixed the problem using an absolute path, though I would greatly appreciate it, if you could also point me in the right direction towards fixing this issue. – nick zoum Jul 24 '19 at 07:32
  • Are there any further actions I have to do? – nick zoum Jul 27 '19 at 00:16
  • I think if you had typescript installed globally you'd be able to circumvent this by having it point to the globally defined TypeScript installation. Obviously that'd create problems if your projects are pointing to different versions of TypeScript though. – mootrichard Jul 27 '19 at 21:34
  • Still a bit unclear, if I should create a new file (do I have to declare it?) under the `lib` directory or if I should use one of the existing files (which one?). Should I use `export` or `declare`? Could you please show an example exporting the `defineModule` function? – nick zoum Jul 30 '19 at 07:56
  • Oh, I figured you already knew how to create your own *.d.ts files and would just add it in there. There are a few examples that show how you can declare and export there elsewhere though https://stackoverflow.com/questions/21247278/about-d-ts-in-typescript – mootrichard Jul 30 '19 at 18:02
  • I do know, but just placing a .d.ts file in the `lib ` folder didnt work, so im asking if I need to include the folder in like typescripts package.json or something – nick zoum Jul 30 '19 at 18:11
  • My bad, it looking a little further into this, the naming convention for creating your own library definition is `lib.*.d.ts` (updated in answer). If you wanted to do something a little bit hacky, you could certainly just add them to `typescript.d.ts` in that folder. – mootrichard Jul 31 '19 at 18:41
  • Figured I would just put the stuff to `typescript.d.ts`. But to access it, I have to do `require("C:\\Users\\...\\AppData\\Roaming\\npm\\node_modules\\typescript\\lib\\typescript")`. That's not very convenient. – nick zoum Aug 01 '19 at 07:12
  • Thanks @mootrichard a lot for your answer, however putting a new file named `lib.*.d.ts` no longer works for the latest TypeScript (4.8 at this moment), it only loads a pre-defined list of files (see `libEntries` in https://github.com/microsoft/TypeScript/blob/9d443b76aac0832d7f3c890441264d39307fe31a/lib/tsserver.js) – peon Jun 21 '22 at 09:21
0

Acknowledgment

This answer was mostly inspired by mootrichard's answer, but since it had to be modified, to work with my project, I am also adding this answer.

Solution

If you press F12 on a global JavaScript function (i.e. eval) a typing declarations file will appear (lib.es5.d.ts), containing JavaScript documentation. You can just add any extra namespaces or function to that file. But you need to use declare and not export.

Example:

//... Other Global JavaScript Declarations

// JavaScript Number Interface
interface Number {
  //...
}

// JavaScript Date Interface
interface Date {
  //...
}

declare function ezDefine(moduleName: string, generator: *): void;
nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • Am I the only one feeling uncomfortable editing files which belong to the `typescript` package that essentially is a vscode dependency? – Z. Zlatev Mar 09 '23 at 14:13