ts-inlay-hints

Welcome to ts-inlay-hints 👋

All Contributors

A guide on how to utilize TypeScript inlay hints in VS Code / Neovim with the TypeScript Language Server

IT Man - Tip #39 - Level Up Your TypeScript: Inlay Hints [Vietnamese]

What is TypeScript inlay hints?

TypeScript inlay hints are inline annotations that appear in your source code while you are coding. They provide additional contextual information about variables, parameters, or function return values. This feature enhances the readability and understanding of your code by providing live insights about your types directly in the code.

Below is a comparison to illustrate how your code looks without and with TypeScript inlay hints:

Without Inlay Hints With Inlay Hints
Without Inlay Hints With Inlay Hints

Here’s the same example, represented as code:

Without Inlay Hints:

function greet(name: string) {
  return `Hello, ${name}!`;
}

let user = "World";
greet(user);

With Inlay Hints:

function greet(name: string): string {
  return `Hello, ${name}!`;
}

let user: string = 'World';
greet(user: string): string;

As you can see, the inlay hints provide extra information about the types of the variables and function return values directly in the code, significantly improving readability and understanding.

How to use

The instructions to set this up are detailed in the following VS Code and Neovim sections.

VS Code settings

In Visual Studio Code, to enable TypeScript inlay hints, follow these steps:

  1. Open settings (File -> Preferences -> Settings or CMD/Ctrl + ,).
  2. Search for “inlay hints” in the search bar.
  3. Look for the “Typescript > Inlay Hints” section. There are several options that can be configured here. You can enable or disable each type of hint individually.
  4. Reload the VS Code for changes to take effect.

VSCode inlayHints

My preferred VS Code Settings

Below is a recommended configuration for VS Code when using inlay-hints. These settings optimize various aspects of the VS Code environment for JavaScript, TypeScript and Deno development. You can copy and paste these settings into your VS Code settings JSON file.

{
  "editor.inlayHints.fontFamily": "JetBrainsMono NF",
  "editor.inlayHints.fontSize": 1,
  "editor.inlayHints.padding": true,
  "javascript.inlayHints.enumMemberValues.enabled": true,
  "javascript.inlayHints.functionLikeReturnTypes.enabled": true,
  // You can set this to 'all' or 'literals' to enable more hints, default is none
  "javascript.inlayHints.parameterNames.enabled": "literals",
  "deno.inlayHints.enumMemberValues.enabled": true,
  "deno.inlayHints.functionLikeReturnTypes.enabled": true,
  "typescript.inlayHints.enumMemberValues.enabled": true,
  "typescript.inlayHints.functionLikeReturnTypes.enabled": true,
  // You can set this to 'all' or 'literals' to enable more hints, default is none
  "typescript.inlayHints.parameterNames.enabled": "literals"
}
Setting Description Image
enumMemberValues If set to true, this setting enables Inlay Hints for enum member values. enumMemberValues
functionLikeReturnTypes If set to true, this setting enables Inlay Hints for function and method return types. functionLikeReturnTypes
parameterNames If set to ‘all’ or ‘literals’, this setting provides Inlay Hints for variable declarations, default values and destructuring assignments. The default setting is ‘none’. parameterNames

VSCode preferred inlayHints

Neovim settings

For Neovim users, TypeScript inlay hints can be enabled using the nvim-lspconfig and typescript.nvim plugins.

Neovim inlayHints

Usage with LazyVim

-- plugins/lspconfig.lua
return {
  "neovim/nvim-lspconfig",
  dependencies = { "jose-elias-alvarez/typescript.nvim" },
  opts = {
    servers = {
      tsserver = {
        settings = {
          typescript = {
            inlayHints = {
              includeInlayParameterNameHints = "all", -- 'none' | 'literals' | 'all'
              includeInlayParameterNameHintsWhenArgumentMatchesName = true,
              includeInlayVariableTypeHints = true,
              includeInlayFunctionParameterTypeHints = true,
              includeInlayVariableTypeHintsWhenTypeMatchesName = true,
              includeInlayPropertyDeclarationTypeHints = true,
              includeInlayFunctionLikeReturnTypeHints = true,
              includeInlayEnumMemberValueHints = true,
            },
          },
          javascript = {
            inlayHints = {
              includeInlayParameterNameHints = "all", -- 'none' | 'literals' | 'all'
              includeInlayParameterNameHintsWhenArgumentMatchesName = true,
              includeInlayVariableTypeHints = true,

              includeInlayFunctionParameterTypeHints = true,
              includeInlayVariableTypeHintsWhenTypeMatchesName = true,
              includeInlayPropertyDeclarationTypeHints = true,
              includeInlayFunctionLikeReturnTypeHints = true,
              includeInlayEnumMemberValueHints = true,
            },
          },
        },
      },
    },
    inlay_hints = {
      enabled = true,
    },
    setup = {
      tsserver = function(_, opts)
        require("typescript").setup({ server = opts })
        return true
      end,
    },
  },
}

If you are using the stable version of Neovim, you need to install lsp-inlayhints in your config:

-- plugins/lsp-inlayhints.lua

-- Disable lsp-inlayhints if that is nightly version, will remove when 0.10.0 is stable
local enabled_inlay_hints = true
if vim.fn.has("nvim-0.10.0") == 1 then
  enabled_inlay_hints = true
end

return {
  {
    "lvimuser/lsp-inlayhints.nvim",
    ft = { "javascript", "javascriptreact", "json", "jsonc", "typescript", "typescriptreact", "svelte" },
    enabled = enabled_inlay_hints,
    opts = {
      debug_mode = true,
    },
    config = function(_, options)
      vim.api.nvim_create_augroup("LspAttach_inlayhints", {})
      vim.api.nvim_create_autocmd("LspAttach", {
        group = "LspAttach_inlayhints",
        callback = function(args)
          if not (args.data and args.data.client_id) then
            return
          end

          local bufnr = args.buf
          local client = vim.lsp.get_client_by_id(args.data.client_id)
          require("lsp-inlayhints").on_attach(client, bufnr)
        end,
      })
      require("lsp-inlayhints").setup(options)
      vim.api.nvim_set_keymap(
        "n",
        "<leader>uI",
        "<cmd>lua require('lsp-inlayhints').toggle()<CR>",
        { noremap = true, silent = true }
      )
    end,
  },
}

My preferred Neovim LSP settings

This is my preferred Neovim configuration for JavaScript, TypeScript and Deno development. You can copy and paste these settings into your Neovim config.

settings = {
  typescript = {
    inlayHints = {
      -- You can set this to 'all' or 'literals' to enable more hints
      includeInlayParameterNameHints = "none", -- 'none' | 'literals' | 'all'
      includeInlayParameterNameHintsWhenArgumentMatchesName = false,
      includeInlayFunctionParameterTypeHints = false,
      includeInlayVariableTypeHints = false,
      includeInlayVariableTypeHintsWhenTypeMatchesName = false,
      includeInlayPropertyDeclarationTypeHints = false,
      includeInlayFunctionLikeReturnTypeHints = true,
      includeInlayEnumMemberValueHints = true,
    },
  },
  javascript = {
    inlayHints = {
      -- You can set this to 'all' or 'literals' to enable more hints
      includeInlayParameterNameHints = "none", -- 'none' | 'literals' | 'all'
      includeInlayParameterNameHintsWhenArgumentMatchesName = false,
      includeInlayVariableTypeHints = false,
      includeInlayFunctionParameterTypeHints = false,
      includeInlayVariableTypeHintsWhenTypeMatchesName = false,
      includeInlayPropertyDeclarationTypeHints = false,
      includeInlayFunctionLikeReturnTypeHints = true,
      includeInlayEnumMemberValueHints = true,
    },
  },
},

Resources

Here are some additional resources that you may find helpful when working with TypeScript inlay hints:

VS Code Extensions

VS Code Comment Queries

This extension enables showing the variable types in your code through annotation syntax and inline prompts.

Total TypeScript VSCode Extension

This extension aims to help you learn TypeScript directly from your IDE. It provides helpful hints on syntax and translates TypeScript’s most cryptic errors.

Neovim Plugins

These plugins can enhance your TypeScript coding experience in Neovim:

lsp-lens.nvim

This plugin displays references and definition info upon functions, similar to JetBrains’ IDEA. You can enable/disable specific requests such as definitions, references, and implementations. It also includes declaration in references.

{
  "VidocqH/lsp-lens.nvim",
  event = "BufRead",
  opts = {
    include_declaration = true, -- Reference include declaration
    sections = { -- Enable / Disable specific request
      definition = false,
      references = true,
      implementation = false,
    },
  },
  keys = {
    {
      -- LspLensToggle
      "<leader>uL",
      "<cmd>LspLensToggle<CR>",
      desc = "LSP Len Toggle",
    },
  },
}

dim.lua

dim.lua is a Neovim plugin that dims unused variables and functions using LSP and Treesitter. It is dependent on nvim-treesitter and nvim-lspconfig.

{
  "narutoxy/dim.lua",
  event = "BufRead",
  dependencies = { "nvim-treesitter/nvim-treesitter", "neovim/nvim-lspconfig" },
  config = true,
}

typescript.nvim

A minimal typescript-language-server integration plugin to set up the language server via nvim-lspconfig and add commands for convenience.

return {
  "neovim/nvim-lspconfig",
  dependencies = {
    {
      "jose-elias-alvarez/typescript.nvim",
      dependencies = {
        "davidosomething/format-ts-errors.nvim",
      },
    },
  },
  ---@class PluginLspOpts
  opts = {
    ---@type lspconfig.options
    servers = {
      tsserver = {
        root_dir = require("lspconfig").util.root_pattern("package.json"),
        single_file_support = false,
        -- refer https://github.com/jose-elias-alvarez/null-ls.nvim/discussions/274#discussioncomment-1515526
        on_attach = function(client)
          client.resolved_capabilities.document_formatting = false -- disable formatting in tsserver in favor of null-ls
        end,
        handlers = {
          -- format error code with better error message
          ["textDocument/publishDiagnostics"] = function(_, result, ctx, config)
            if result.diagnostics == nil then
              return
            end

            local idx = 1

            while idx <= #result.diagnostics do
              local entry = result.diagnostics[idx]
              local formatter = require("format-ts-errors")[entry.code]
              entry.message = formatter and formatter(entry.message) or entry.message
              if entry.code == 80001 then
                table.remove(result.diagnostics, idx)
              else
                idx = idx + 1
              end
            end
            vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx, config)
          end,
        },
        -- add keymap
        keys = {
          { "<leader>co", "<cmd>TypescriptOrganizeImports<CR>", desc = "Organize Imports" },
          { "<leader>cR", "<cmd>TypescriptRenameFile<CR>", desc = "Rename File" },
        },
        -- inlay hints
        settings = {
          typescript = {
            inlayHints = {
              -- You can set this to 'all' or 'literals' to enable more hints
              includeInlayParameterNameHints = "literals", -- 'none' | 'literals' | 'all'
              includeInlayParameterNameHintsWhenArgumentMatchesName = false,
              includeInlayFunctionParameterTypeHints = false,
              includeInlayVariableTypeHints = false,
              includeInlayVariableTypeHintsWhenTypeMatchesName = false,
              includeInlayPropertyDeclarationTypeHints = false,
              includeInlayFunctionLikeReturnTypeHints = true,
              includeInlayEnumMemberValueHints = true,
            },
          },
          javascript = {
            inlayHints = {
              -- You can set this to 'all' or 'literals' to enable more hints
              includeInlayParameterNameHints = "literals", -- 'none' | 'literals' | 'all'
              includeInlayParameterNameHintsWhenArgumentMatchesName = false,
              includeInlayVariableTypeHints = false,
              includeInlayFunctionParameterTypeHints = false,
              includeInlayVariableTypeHintsWhenTypeMatchesName = false,
              includeInlayPropertyDeclarationTypeHints = false,
              includeInlayFunctionLikeReturnTypeHints = true,
              includeInlayEnumMemberValueHints = true,
            },
          },
        },
      },
    },
    -- Enable this to enable the builtin LSP inlay hints on Neovim >= 0.10.0
    inlay_hints = {
      enabled = true,
    },
    format = {
      timeout_ms = 10000, -- 10 seconds
    },
  },
}

tsc.nvim

This Neovim plugin provides an asynchronous interface to run project-wide TypeScript type-checking using the TypeScript compiler (tsc).

return {
  {
    "dmmulroy/tsc.nvim",
    auto_open_qflist = true,
    opts = {
      auto_close_qflist = false,
      enable_progress_notifications = false, -- disable notification
      -- support monorepo
      flags = {
        build = true,
      },
    },
    keys = {
      { "<leader>ck", "<cmd>TSC<CR>", desc = "Check TypeScript error" },
    },
  },
}

Tips

Bob - A Guide for Easy Switching Between Neovim Versions

Bob is a versatile, cross-platform Neovim version manager that simplifies the process of switching between different versions of Neovim. It supports a range of commands for version management and comes with several features that offer added convenience.

Here’s how you can use it:

getNF - The Convenient Way to Install NerdFonts

getNF is an efficient and intuitive way to install NerdFonts. NerdFonts are developer-targeted fonts that come packed with a plethora of glyphs (icons) from popular ‘iconic fonts’ such as Font Awesome, Devicons, Octicons, and others.

Installation

To install getNF, follow these steps:

  1. Clone the getNF repository from GitHub:
    git clone https://github.com/ronniedroid/getnf.git
    
  2. Move into the getnf directory:
    cd getnf
    
  3. Run the install.sh script:
    ./install.sh
    

Now, you’re all set to enrich your coding experience with an array of Nerd Fonts. Enjoy!

Author

👤 Huynh Duc Dung

Show your support

Give a ⭐️ if this project helped you!

kofi paypal buymeacoffee

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Mika Vilpas
Mika Vilpas

📖
Dung Duc Huynh (Kaka)
Dung Duc Huynh (Kaka)

💻 📖

This project follows the all-contributors specification. Contributions of any kind welcome!