val-town / codemirror-ts

lint, hover, and autocomplete extensions for CodeMirror + TypeScript
https://val-town.github.io/codemirror-ts/
ISC License
137 stars 12 forks source link

How to use types from a different file in the vfs? #25

Closed liontariai closed 4 months ago

liontariai commented 4 months ago

Hi,

to me it seems like the update to v2 which introduced the configuration via a Facet may have removed the capability to work with multiple files?

I haven't found a way to use the tsFacet in a way, that allows me to inject types from a second file.

I have one file called types.ts and one file called index.ts. I set up everything like in the docs with index.ts and the autocomplete, lint and hover works for everything I write in the index.ts, as this is my main file I have in my CodeMirror editor and I keep the ts vfs in sync with the tsSync extension. However, there seems to be no way to import types from another file now?

An import statement like import { X } from "./types"; won't work. The autocomplete gives me the filename types, because it's in the fsMap for my @typescript/vfs filesystem, but from there I don't get any further. Which makes sense, because all the extensions only look into my index.ts. I looked this up in the code in this repo, and I mean it makes sense, but how can I have an import from a separate file then?

liontariai commented 4 months ago

I solved it, sorry for spamming here, but it wasn't obvious at all for me how to achieve this seemingly simple thing. So one has to put the types file in "./node_modules/@types/types/index.d.ts" in the fsMap and put typeRoots: ["./node_modules/@types"], in the compilerOptions.

Perhaps this helps someone

jozefRudy commented 2 months ago

hi, just came across this comment. maybe i am forgetting something, for me does not seem to work (to import exported item from index.d.ts.

here is my code

const fsMap = await createDefaultMapFromCDN(
      {
        target: ts.ScriptTarget.ES2022,
        typeRoots: ["./node_modules/@types"],
      },
      "3.7.3",
      true,
      ts,
    );

const system = createSystem(fsMap);

const compilerOpts = {};
this.env = createVirtualTypeScriptEnvironment(system, [], ts, {});

let editor = new EditorView({
  doc: `import { a } from "./types";`,
  extensions: [
    basicSetup,
    javascript({
      typescript: true,
      jsx: false,
    }),
    tsSync(),
    tsLinter(),
    autocompletion({
      override: [tsAutocomplete()],
    }),
    tsHover(),
    tsFacet.of({ env: this.env, path: "index.ts" }),
  ],
  parent: this.container().nativeElement,
});

this.env.createFile(
  "./node_modules/@types/types/index.d.ts",
  "export const a = 1;",
);

would appreciate help on how you made it work or from the author. @liontariai basically import { a } from "./types" should correctly import a, but it seems types is unrecognized.

liontariai commented 2 months ago

I'm not sure and not able to test right now, but have you tried doing smth like

declare const a = 1;

?

jozefRudy commented 2 months ago

i think the problem will be in the module? i am getting this exact message around "./types" ->

    Cannot find module './types' or its corresponding type declarations.

I just tried declare, same thing. I will try to search around. @liontariai

jozefRudy commented 2 months ago

so for anyone interested, the problem was, that file needs to be preceeded by '/'. e.g.

    fsMap.set(
      "/file-with-export.ts",
      `export const helloWorld = "Example string";`,
    );

then one can import from

import {helloWorld} from "./file-with-export";