11

VSCode Version: 1.20.0

First, what I think I know about Visual Studios Code IntelliSense:

  1. The presence of a tsconfig.json/jsconfig.json should indicate to vscode that the directory is a TypeScript/JavaScript project (docs). This means that IntelliSense should be aware of all .js and .ts files in the directory (respecting the include and exclude config properties), and all classes/definitions exported by those files without having to explicitly reference them.
  2. In any case, you can make IntelliSense aware of classes/definitions exported by a file by explicitly referencing said file. This can be done via require(), import, or /// <reference path="..." />.
  3. You can mix TypeScript and JavaScript files.

Given these preconceptions, I can not get vscode to work as expected. See the simple example project below. The objective is to be able to use the Person class definition defined in test.d.ts typed definition TypeScript file in the test.js JavaScript file. However, IntelliSense complains that it is unaware of the Person class:

vscode screenshot

Note that IntelliSense works with packages that have been npm install-ed.

Given assumption #1, simply including the tsconfig.json file should be all I need. Even so, I also tried explicitly listing typings/test.d.ts and test.js in includes. I also tried listing typings in compilerOptions.typeRoots.

Given assumption #2, including a triple-slash reference directive in test.js to ./typings/test.d.ts should work.

There is a lot of outdated information out there because vscode has changed the way it handles configurations, typings, etc. I have read everything I could find but I can't get it to work.

Any ideas? What am I missing here?


tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "lib": ["es6"],
    "allowJs": true,
    "checkJs": true
  },
  "exclude": [
    "node_modules"
  ]
}

test.js

/// <reference path="./typings/index.d.ts" />

/** @type {Person} */
const p = {};

typings/test.d.ts

export class Person {
  name: string;
  age: number;
}
5
  • 1
    Change export class to declare class
    – Alex
    Commented Feb 8, 2018 at 20:44
  • @Alex That worked! But why is it necessary? Looking at other typed definitions I see exports but not declares. Here is an example.
    – Mike
    Commented Feb 8, 2018 at 21:51
  • Well, you can use export class and import it where it needed: import {Person} from "./typings/test";
    – Alex
    Commented Feb 8, 2018 at 21:56
  • Hmm. What if you are using CommonJS (require())? Can't require() a TypeScript file.
    – Mike
    Commented Feb 8, 2018 at 22:00
  • No idea. short comment
    – Alex
    Commented Feb 8, 2018 at 22:32

1 Answer 1

19

As of the May 2018 (v1.24) release of VSCode, the TypeScript version was updated to 2.9 which includes the ability to import() types.

This means we can also use import() in JSDocs like so:

/** @type {import('./typings/test').Person} */
const p = {};

and/or

/** @typedef {import('./typings/test').Person} Person */

/** @type {Person} */
const p = {};

This also allows us to reference types defined in other JavaScript files even if they are not exported. No tsconfig.json or any other configuration file required and no need to use TypeScript files. Full example:


func1.js

/**
 * @typedef MyStruct
 * @property {string} fu
 * @property {number} bar
 */

module.exports = function func1() {
  // ...
}

func2.js

/**
 * @param {import('./func1').MyStruct} options 
 */
module.exports = function func2(options) {
  // ...
  // IntelliSense definition for this function:
  // func2(options: MyStruct): void
}

You can also reference types from node modules:

/** @type {import('async').AsyncCargo} */

Note: I did find a possible bug. If the file you import() does not export anything, intellisense breaks.

4
  • Too bad that import() breaks jsdoc completely, i.e. no way to parse/compile documentation anymore.
    – user64204
    Commented Oct 30, 2020 at 17:49
  • What do you mean? I just tested the above in latest vscode (1.50.1) and it still works fine.
    – Mike
    Commented Nov 1, 2020 at 22:39
  • I mean jsdoc cannot parse import() namepaths. What works in vscode is irrelevant, because it uses typescrpt tsc and not jsdoc. I.e. you cannot generate documentation from source.
    – user64204
    Commented Nov 3, 2020 at 10:56
  • Ahhh I see what you mean.
    – Mike
    Commented Nov 3, 2020 at 14:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.