Dalius's blog

Sunday, November 15, 2020

Typescript and ALE

UPDATE 2022-08-02: My recommendation is to use “Typescript and Neovim LSP” as it allows to do more and discover more what might be relevant during development.

In this article I will describe how to use Vim ALE for Typescript development. As well I will give a little bit background why I think you might consider this solution vs other solutions from the Vim’s world.

Configuration

At first follow ALE installation instructions. E.g. if you use vim-plug then add following line:

Plug 'dense-analysis/ale'

I recommend installing deoplete.nvim as well (while I believe you can use ALE without deoplete). The best part here is that you don’t need to install anything else because ALE supports tsserver. All you need to do now is to bind commands to something you want. I use following mappings:

nmap <silent> <leader>aj :ALENext<cr>
nmap <silent> <leader>ak :ALEPrevious<cr>

Pressing ,aj/,ak in my case jumps to next/previous info/warning/error message in file.

autocmd FileType javascript map <buffer> <c-]> :ALEGoToDefinition<CR>
autocmd FileType typescript map <buffer> <c-]> :ALEGoToDefinition<CR>
autocmd FileType typescriptreact map <buffer> <c-]> :ALEGoToDefinition<CR>

c-] is mapped to go to definition in javascript/typescript files. I mapped this by file type because c-] is used for navigation using tags in other situations in Vim.

nnoremap K :ALEHover<CR>

ALEHover command show information about word under cursor (e.g. variable’s type).

nnoremap <silent> gr :ALEFindReferences<CR>

Use gr when you want to find locations where your function is used.

nnoremap <leader>rn :ALERename<CR>

If you need to rename something in a smart way use this command.

nnoremap <leader>qf :ALECodeAction<CR>
vnoremap <leader>qf :ALECodeAction<CR>

Lastly you can use code actions. Let’s say you are missing import and there is error showing that. You can use ,qf in normal mode to import missing library. As well you can select some text in visual mode and extract your code to function or method. Actually tsserver supports more code actions.

Disclaimer: I have implemented code actions in ALE so you can complain to me if something is not working as intended 😅.

That’s the main features for Typescript development but there are more.

Fixing errors

Most probably you use prettier and eslint in your projects. ALE will lint your files using those tools if it will manage to find them (again nothing to install). Potentially you want to fix some of your files as well with those tools. You can do it in this way:

let js_fixers = ['prettier', 'eslint']

let g:ale_fixers = {
\   '*': ['remove_trailing_lines', 'trim_whitespace'],
\   'javascript': js_fixers,
\   'javascript.jsx': js_fixers,
\   'typescript': js_fixers,
\   'typescriptreact': js_fixers,
\   'css': ['prettier'],
\   'json': ['prettier'],
\}

As well enable fix on save:

let g:ale_fix_on_save = 1

Other goodies

And there are more. ALE support auto-import on completion. I don’t find this feature useful as it sometimes import random libraries I don’t want to but you can enable it like this:

let g:ale_completion_autoimport = 1

You can change sign symbols as well. E.g.:

let g:ale_sign_error = "🐛"
let g:ale_sign_warning = "⚠️"
let g:ale_sign_info = "ℹ"

Neovim users might want to enable virtual text (at least I found it practical):

let g:ale_virtualtext_cursor = 1
let g:ale_virtualtext_prefix = "🔥 "

Other solutions

I have tried out other Typescript tools for Vim as well so let’s review them again.

CoC

CoC is recommended tool for Vim developers who need to work with Typescript. I have tried it as well (read here). First impression was good but I have some problems with CoC:

  • It slows down Vim sometimes. Switching tabs took more than 1 second while working in large projects. I have no idea why it happens but it does.

  • You have to take extra steps when you use nvm/fnm.

  • IMHO importing VS Code extensions to Vim make Vim poorer as ecosystem. While tools in CoC ecosystem are good but in some situations they actually make you poorer. E.g. coc-word gives you auto-complete for 10k most popular words what is good but combine deoplete with ujihisa/neco-look, install write-good (it works out-of-the-box with ALE) and you have much better tools.

There is at least one thing you might be missing from CoC if you decide to migrate to ALE. CoC fixes imports in Typescript files after file rename. It does this by using watchman and by using tsserver command getEditsForFileRename. This can be implemented in ALE as well as code edits part is available already. While I think that’s not the only way how file rename handling can be implemented.

UPDATE 2022-08-02: there is ALEFileRename that partially solves this.

LSP

LSP (as vs tsserver) is another way how to use Typescript with Vim. There are a lot of LSP client implementations for Vim and Neovim has native LSP support (I have written about it here). The main problem with LSPs is that tsserver does not support LSP natively (and it does not seem that they want to do it fast). So you have to use typescript-language-server what is wrapper around tsserver and you end-up adding yet another server into your configuration. As well you now have problem with nvm/fnm (like with CoC).

While I believe that LSP might be the future one day. That actually might be faster than expected.

UPDATE 2024-06-05: typescript-tools.nvim is the way to go.

nvim-typescript

nvim-typescript is yet another tsserver implementation for Vim. Initially it looked very promising but at some time author managed to brake it somehow (at least for me) and I had to look for different tool. As of today ALE has better support than nvim-typescript for tsserver.