Let’s get Vim set up to use TS…with a twist. We’re using TS tooling on regular JS. We’ll add JSDoc annotations only.

This is fairly straightforward if you want to just work on TS. This gets fun because we’re using TS tools on JS.


Ha. This is the short version. Get lost.


tsc is the TypeScript compiler. You can run it like this.

npx tsc index.ts

To just get errors

npx tsc index.ts --noEmit

Define options in tsconfig.json or supply as command line args.


To support TS syntax highlighting, add https://github.com/leafgarland/typescript-vim.

.ts files will work automatically. You can use this syntax for .js files too to improve JSDoc annotations. Set the syntax manually since they are not .ts files with :set syntax=typescript.


Use these snippets to verify your syntax works.

  // foo.js, Don't forget to :set syntax=typescript.
   * @typedef {Object} Dude
   * @property {string} name
   * @property {number} age

   * @param {Dude} dude
   * @param {number} foo
   * @returns {number}
  export const blah = (dude, foo) =>
      ? foo
      : foo * 2

  blah(1, 2)
  // foo.ts
  type Dude = {
   name: string,
   age: number,

  export const blah = (dude: Dude, foo: number): number =>
      ? foo
      : foo * 2

  blah(1, 2)


Now that we’ve got syntax highlighting, we want to tap into the type system. Much of the value comes from tsc as we discussed. We can run it manually to verify our code.

  npx tsc foo.ts --noEmit

  foo.ts:11:6 - error TS2345: Argument of type '1' is not assignable to parameter of type 'Dude'.

  11 blah(1, 2)

  Found 1 error.

We can do it for js too, if we tell tsc to use include js.

  npx tsc foo.js --noEmit --allowJs --checkJs
  foo.js:17:6 - error TS2345: Argument of type '1' is not assignable to parameter of type 'Dude'.

  17 blah(1, 2)

  Found 1 error.

Instead of doing this like a Jabroni, we can add https://github.com/Quramy/tsuquyomi. It will tie in linting and does omni-complete based on context.


Once installed, check that it works with foo.ts above. You should see it when you save in the quickfix list and/or reported by your linter. There are a lot of other cool features you can explore described on the README.


JS vs TS

We are partially using TS. We’re defining types in JSDoc annotations so the source is still JS. As such, Tsuquyomi doesn’t run on our js files.

To get this all to work, add this

  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
  "include": [

and to your .vimrc

let g:tsuquyomi_javascript_support = 1

The last thing we need is to set the omnifunc (for completion) and the syntax conditionally. We’re using .js instead of typescript, so it’s not automatic. First, figure out what Vim is calling your .js. Depending on other plugins, they may be something other than javascript.

:set filetype?

Now add an autocommand for this file type. We may as well set the syntax while we’re at it.

augroup typescript_js
  autocmd FileType javascript.jsx setlocal omnifunc=tsuquyomi#complete
  autocmd FileType javascript.jsx setlocal syntax=typescript
augroup END

Eventually, this crap will work.


Annotations start with /** not /*.

/* @type {number} */
let y = 'asdf'