VSCode Settings
Light
help

Troubleshooting

  • Stale path / environment variables in terminal

    • Try completely restarting VSCode - close all windows and relaunch
    • Try running VSCode as an administrator; this can often fix path expansion issues
    • Check which shell you are using as the intergrated terminal

      • You can override with settings.json -> terminal.integrated.shell.{OS}
  • TypeScript import autocomplete keeps using absolute or incorrect relative paths

    • Try setting settings.json -> "typescript.preferences.importModuleSpecifier": "relative"

Settings

For my personal settings, see settings.json.

Disable annoying word autocomplete

{
	"editor.wordBasedSuggestions": false,
	"javascript.suggest.names": false
}

Setup basic code formatting rules

{
	"editor.tabSize": 4
}

Disable CRLF (\r\n) endings on Windows

{
	"files.eol": "\n"
}

Force indent style

If you really want to ensure a specific indent style in a shared repo, this is a forceful way to do so, in your .vscode/settings.json:

{
	"editor.insertSpaces": true,
	"editor.tabSize": 4,
	"editor.detectIndentation": false,
	"editor.formatOnSave": true,
	"editor.autoIndent": "full"
}

Extensions:

Per workspace settings

You can control settings per root directory (workspace/project) through {WORKSPACE_ROOT}/.vscode/settings.json.

  • This file will be automatically created if you touch a workspace level setting (through the GUI), but you can also manually create it:

    • mkdir .vscode && touch .vscode/settings.json

Recommended extensions file

You can add a file (extensions.json) to your workspace .vscode folder, so that when other devs checkout your code, VSCode will recommend for them to install the extensions that will help them the most. Read more here.

Javascript Type Safety

There are are a bunch of options for getting some type-safety with JS in VScode, and better intellisense. Of course, you are free to also use linters, like ESLint (see my JS DevOps Cheatsheet), but that is not the only option. There is actually built-in type checking options!

Triggering the built in JS Type Checker options:

  • Add //@ts-check to top of JS file
  • Add setting to preferences:

    • "javascript.implicitProjectConfig.checkJs": true

      • Can be added to either global or workspace settings.json
  • Add a tsconfig.json or jsconfig.json file in the project to control the settings

Note that these built in options internally ("salsa" engine?) actually use TypeScript features to do the checking/linting (you can read more about that: 1). And to augment the interpretation/inferred types of JS, you can use JSDoc comments. Note that this syntax is different from ESLint.

/**
 * @type {google.maps.StreetViewPanorama}
 */
let pano = this.mapObjs.svPano;

/**
 * @type Array<{localPath:string, fullPath: string}>
 */
let filePaths = [];

/**
 * @typedef {"Hello" | "World"} MyStringOptions
 */

// You can even re-use types!
/**
 * @typedef {Object<string, any>} Person
 * @property {string} name - Person's preferred name
 * @property {number} age - Age in years
 * @property {boolean} likesCilantro - Whether they like cilantro
 * @property {string} [nickname] - Optional: Nickname to use
 */


/**
 * @type Person
 */
let phil = {
	name: 'Phil Mill',
	age: 25,
	likesCilantro: true
}

/**
 * @type Person
 */
let bob = {
	name: 'Robert Smith',
	age: 30,
	likesCilantro: true,
	nickname: 'Bob'
}

/**
 * 
 * @param {Person} personObj 
 */
function analyzePerson(personObj){
	// Intellisense will fully know the type of personObj!
	console.log(personObj.name);
}

WARNING: JSDoc TS annotations MUST be in a comment block (multi-line) comment to be be parsed. They are ignored in single line (//) comments!!!

And you can even install module type defs, like thosed from @types. This works the same as in TypeScript, so see my notes about "including external type definition files" for details. For most JS projects, since you are likely missing a tsconfig.json file, the easiest option might be a one-off triple-slash directive usage.

Unfortunately, for globals, it looks like JSDoc or inline comments are not supported (issue #15626, doc change) the only way to tell VSCode about those is through a TypeScript "ambient declaration file" (e.g. *.d.ts file). For example, you can create a globals.d.ts file, declare your globals / interfaces / etc., and VSCode's type checker will pick up on it, despite your project being JS code.

Of course, you can always turn off checking, or use `/*

Advanced JSDoc / TS annotation usage:

Important reference material

Annotating destructured parameters

If you want to annotate the type of variables that are assigned via destructuring, it can be a little complicated with JSDoc.

For destructuring directly, it looks like this:

/**
 * @typedef {Object<string, any>} DestructuredUser
 * @property {string} userName
 * @property {number} age
 */
/** @type {DestructuredUser} */
const {userName, age} = getUser();

For annotating on a function argument:

/**
 * @typedef {Object<string, any>} DestructuredUser
 * @property {string} userName
 * @property {number} age
 */
/** @param {DestructuredUser} param */
function logUser({userName, age}){
	console.log(`User ${userName} is ${age} years old.`);
}

Annotating function signatures / function as a type

This looks pretty similar to TS - return type should come after arguments with colon:

/**
 * @typedef {function(string): string} StringProcessor
 */

Here are some practical examples:

/**
 * @typedef {function(string): string} StringProcessor
 */

// Annotating single variable
/**
 * @type {StringProcessor}
 */
const upperCaser = (input) => {
	return input.toUpperCase();
}

// Within another typedef
/**
 * @typedef {Object<string, StringProcessor>} StringProcessorsCollection
 */
/**
 * @type {StringProcessorsCollection}
 */
const myStringMethods = {
	lowerCase: function(input) {
		return input.toLowerCase();
	}
}

Importing external / exported types directly in JSDoc

This is kind of a crazy feature but, at least in VSCode, you can actually import types from specific modules by using import directly within a JSDoc block! For example, if we wanted to explicitly type a variable as NodeJS's "fs" -> "Stats" type, we could use:

/**
 * @type {import('fs').Stats}
 */
let fsStats;

You can read a bit more about this feature (implemented in 2018) in various spots:

Issues

If you run into issues with this, here are some things to check or try:

  • "cannot find name ___ ts(2304)"

    • VSCode seems to have an issue with ambient declaration files (*.d.ts) being picked up without a tsconfig.json file. You can either:

      • Add a tsconfig.json file

        • Or:
      • Use a triple slash directive at the top of the file, for example: /// <reference path="../types.d.ts"/>
      • Keep the ambient type file open while editing (right click tab, "Keep Open") - quick hack
    • Can you add an import that brings in the namespace'd type?
    • Is the type declared under a namespace or module that doesn't match where you are trying to use the type?
    • If you have used import or export in a TS file that you are trying to use as an ambient type declaration file, make sure types are wrapped with declare global {}.

Further reading

Here are some more guides on trying to get the benefits of TypeScript in JS (type-safety):


Coming from Notepad++ / "where is X?"

If you are coming from using Notepad++, or a vastly different IDE, you might be looking for certain things. For example:

  • "Show all characters"

    • In Notepad++, this shows whitespace characters (\t, \s, etc.), as well as EOL (end of line) characters (\r or \n). I have not a single method to do both on VSCode, but you can do them separately.

      • Whitespace: Menu -> View -> Render Whitespace
      • EOL: There is an extension that shows them

Searching

  • You can use regex
  • You can filter your search by specific files and by directory

    • See guide here
    • Uses glob syntax
    • Use , to separate multiple patterns
    • Use ! to negate a pattern
  • You can exclude files and directories

    • Inherits settings from .gitignore and global settings

Linting / Formatting Controls

Built-in

First, I want to point out that you can customize settings per language in VSCode, no extension required. Just put the language specifier as the JSON key, and then the settings as the object value. Like so:

{
	"editor.tabSize": 4,
	"[php]": {
		"editor.tabSize": 2
	}
}

You can even specify certain actions to be ran after certain file types are saved, by using editor.codeActionsOnSave under a language specifier!

If you are have multiple language formatting extensions installed, and want to tell VSCode which one to use per language, that is another thing you can do with settings:

{
	"[php]": {
		"editor.defaultFormatter": "vscode.php-language-features"
	}
}

JS

Check out my notes here.


Building an extension

For right now, my only public notes on this are on my blog: https://joshuatz.com/posts/2019/building-a-vscode-extension-some-tips-and-tricks/

Markdown Source Last Updated:
Thu Jan 23 2020 18:43:15 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Mon Aug 26 2019 07:49:42 GMT+0000 (Coordinated Universal Time)