5

I'm trying to create a really simple website with:

  • A few JavaScript files that are directly included in the index.html
  • No modules / import statements
  • No bundling system or direct compilation step
  • No requirement for a server to be run (so index.html can be double-clicked without CORS issues)

BUT I'd love to be able to use TypeScript's @ts-check or jsconfig.json within VS Code, and for it to understand the global scope of the code across JavaScript files. However, I'm finding that it's unable to jump to definitions between JavaScript files (or at least, inconsistently?).

Is there a way to tell the TypeScript compiler that all the JavaScript files are in global scope together, and to use the correct order of evaluation from the index.html?

Joseph Humfrey
  • 2,974
  • 2
  • 23
  • 34

1 Answers1

5

Use "js/ts.implicitProjectConfig.checkJs": true in VSC config (or // @ts-check in files) and reference other files with /// <reference path="[...]" />

/// <reference path="other.js" />

somethingDefinedInOtherJS; // no error, f12 go to definition works

See Triple-Slash Directives docs for TS for more info.

Charlton Provatas
  • 2,184
  • 25
  • 18
myf
  • 9,874
  • 2
  • 37
  • 49
  • Thanks! Hmm I'm wondering whether there's something more fishy going on. I don't see errors, but in reference to `World.x` that's defined in `world.js`, it can jump to `World` but can't find `x`. It's defined as `const World = { x: "example" };`. Works in one file but not another with identical setup?! – Joseph Humfrey Dec 19 '19 at 11:39
  • Ah, I think the compiler got confused when I tried to have a function with a default parameter like this: `const World = { x: () => {}, y: function(blah = World.x()) }`. After removing, everything works fine...! – Joseph Humfrey Dec 19 '19 at 11:52
  • I'm not completely sure what depth "exported" context of referenced files have (I'd assume there is no limit) and I cannot repro described problem RN (i.e. I see `World.x` in intellisense in file referrencing definition). Only time I've encountered confusing language server behaviour was when I had "duplicate global symbols" in two distinct files - apparently *opened* file sometimes matters somehow and even non-referrencing files thought I'm using wrong definitions. But it was quite a long time ago. Generally I use similar setup as yours, rely heavily on JSDoc types and it works pretty well. – myf Dec 19 '19 at 12:01
  • Here's a repro: https://github.com/joethephish/ts-check-bug (it can't find `x on `Obj.x` in `one.js`, but works if you comment out `f` in `two.js`). And yeah I found the exact same thing about open files. As soon as you close them it loses references unless you use the `/// ` thing. Thanks for the tip! – Joseph Humfrey Dec 19 '19 at 12:14
  • Ah, even simpler. Nothing to do with cross-file references, I clearly just confused it: https://gist.github.com/joethephish/e22b53f0ae4212137dca1bb900b6f1f1 – Joseph Humfrey Dec 19 '19 at 12:20
  • 1
    Yup, can confirm: using `Obj` or its property in default param of `Obj` method seems borked. I can quite relate to language server's confusion, because Obj is not "fnished" at a time of method definition. Maybe related quip: `const a = {prop:a} // ReferenceError: can't access lexical declaration 'a' before initialization` – myf Dec 19 '19 at 12:37