How to use ESLint to Check TypeScript Code for Issues
Though VSCode includes TypeScript language support which helps us pick up TypeScript errors in our TypeScript code, we'll introduce more robust code checking with ESLint - a popular open-source JavaScript/TypeScript linting tool.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Linting with ESLint
📝 This lesson's quiz can be found - here.
🗒️ Solutions for This lesson's quiz can be found - here.
Though VSCode includes TypeScript language support which helps recognize errors in our TypeScript code, we'll probably need more robust code checking. As an example of something we might want to forbid is preventing a variable from ever having the any
type. TypeScript won't stop us since any
is a valid basic type but as a preference, we probably don't want to have code built in our app that has the any
type since it removes the benefits of type checking.
This is where linting comes. Linting (i.e. code checking) is a process that analyzes code for potential errors. When it comes to linting JavaScript and/or TypeScript code, ESLint is the most popular library to do so. It's configurable, easy to introduce, and comes with a set of default rules.
To introduce linting into our app and take advantage of our code editor, we'll first install the VSCode ESLint extension. The VSCode ESLint extension allows us to integrate ESLint into VSCode to help provide warnings, issues, and errors in our editor.
Once the VSCode ESLint extension is installed, we'll go ahead and install a few other development dependencies that we'll need to enable ESLint configuration into our app. We'll install:
eslint
: the core ESLint library@typescript-eslint/parser
: parser that will allow ESLint to lint TypeScript code@typescript-eslint/eslint-plugin
: plugin when used in conjunction with@typescript-eslint/parser
contains many TypeScript specific ESLint rules.
server $: npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
.eslintrc.json
We'll introduce an .eslintrc.json
configuration file in the root project directory. The .eslintrc.json
file is the configuration file that'll dictate the ESLint set up of our application. We'll look to introduce a couple of options to our ESLint configuration file.
parser
parser
"parser": "@typescript-eslint/parser",
ESLint depends on a parser to read and translate JavaScript code for it to understand. The default ESLint parser (ESpree) doesn't recognize TypeScript code. The @typescript-eslint/parser
is probably the most widely used and supported parser for TypeScript code, and the one installed in our app.
parserOptions
parserOptions
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
The parserOptions configuration allows us to specify the language options we want ESLint to support. By default, ESLint supports ES5. We'll set the ecmaVersion
to 2018
to allow us the use of modern ES features in our app. sourceType: module
to declare that we're using ES6 modules in our app.
extends
extends
"extends": ["plugin:@typescript-eslint/recommended"],
The extends
option allows us to extend the rules from a certain plugin with which we've picked @typescript-eslint/recommended.
env
env
"env": { "node": true },
env
dictates which environment our ESLint script is expected to run. Every environment has its own set of particular global variables so we've stated that we're in the node
environment.
This lesson preview is part of the The newline Guide to Building Your First GraphQL Server with Node and TypeScript course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to The newline Guide to Building Your First GraphQL Server with Node and TypeScript, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:17] Though VS code includes TypeScript language support, which helps us pick up simple errors in our TypeScript code, we'll probably want to introduce more robust code checking. For example, assume we wanted a variable to never have the any type.
[00:18 - 00:39] Now TypeScript won't stop us here since any is a valid TypeScript type, but as a preference, we probably don't want to have code built in our app that has this particular type since it removes the benefits of TypeScript. This is where Linting comes in, or more particularly in our case, ES Lint.
[00:40 - 00:55] For those who don't know what Linting is, Linting or sometimes recognized as code checking is a process of running a program that will analyze code for potential errors. When it comes to Linting, JavaScript and TypeScript code, ES Lint is the most popular library to do so.
[00:56 - 01:14] It's configurable, easy to introduce, and comes with a set of default rules. To introduce Linting into our app and take advantage of our code editor, we'll first install the ES Lint VS code extension.
[01:15 - 01:31] Once installed, we'll now go ahead and install a few other development dependencies we'll need to enable ES Lint configuration into our app. We'll install the ES Lint package.
[01:32 - 01:55] We'll install the @TypeScript ES Lint parser package and we'll also install the @TypeScript ES Lint, ES Lint, plugin package. ES Lint package is the core ES Lint library we'll use.
[01:56 - 02:22] The @TypeScript ES Lint parser package is a parser that will allow ES Lint to L int TypeScript code. And the @TypeScript ES Lint ES Lint plugin package is a plugin that when used in conjunction with the @TypeScript ES Lint parser package contains a bunch of TypeScript specific ES Lint rules we'll use in our app.
[02:23 - 02:46] Next, we'll introduce a .es Lint RC JSON file in the root server project directory. Similar to how the .ts config file was responsible in configuring our Type Script compiler, the ES Lint RC JSON file will be responsible in configuring the ES Lint setup of our application.
[02:47 - 02:58] Now ES Lint actually accepts different file formats for this file. We could use a .js format, a diagonal format, but we'll stick with a .json format.
[02:59 - 03:11] Next we'll look to introduce a couple of options to our ES Lint configuration. We'll first introduce a parser option.
[03:12 - 03:23] parser will be to specify how we want to read and translate JavaScript code for it to understand. The default ES Lint parser, es-pre, doesn't recognize TypeScript code.
[03:24 - 03:39] So we'll use the @TypeScript ES Lint parser. @TypeScript ES Lint parser is probably the most widely used and supported parser for TypeScript code and is the one we've just installed.
[03:40 - 03:53] Next, we'll define a parser options field. The parser options configuration allows us to specify the language options we want ES Lint to support.
[03:54 - 04:03] By default ES Lint supports ES5. To here we'll define a ES ECEMA version field.
[04:04 - 04:12] ECMA version field. Which allows us to state the version of ECMA script syntax we'll use in our app .
[04:13 - 04:25] We'll go ahead and say 2018 to allow for the parsing of modern ECMA script features. Here we'll also define a source type field.
[04:26 - 04:33] We'll pass in a value of module. This allows us to say that we're using ES6 modules in our app.
[04:34 - 04:44] We'll then define the root level in extends field. Extends allows us to extend the rules from a certain package.
[04:45 - 05:02] In this particular case, we'll specify the TypeScript ES Lint recommended package to extend. So we'll say plugin at TypeScript ES Lint recommended.
[05:03 - 05:13] Next, we'll define an environment field. The environment field dictates which environment our ES Lint script is expected to run.
[05:14 - 05:23] Every environment has its own set of particular global variables. So we'll go ahead and state that we're in the node environment.
[05:24 - 05:34] This will help us recognize or help the environment recognize unique node definitions. And then finally we're going to define a rules field.
[05:35 - 05:49] Rules is where we can declare individual ES Lint rules we want in our app. Here's where we can override the rules from the TypeScript ES Lint recommended package we're extending or where we can even introduce new rules.
[05:50 - 05:59] The TypeScript ES Lint recommended package comes with a rule for indenting. Now prettier handles all the indenting formatting for us.
[06:00 - 06:11] So as a result and for preference, we'll turn off any indent formatting rules. We'll explicitly turn off the indent rule by specifying indent off.
[06:12 - 06:26] And we'll also explicitly turn off the @TypeScript ES Lint indent rule by turning that off as well. We'll now save our changes and we'll stop here for now.
[06:27 - 06:45] Similar to how you may not really understand what's happening in the TS config file, if you don't really understand every option here, that isn't really a problem. The main takeaway from this is that the ES Lint RC JSON file is sort of the configuration file for how we want to configure ES Lint in our development climate.
[06:46 - 06:57] We specify parser to basically tell ES Lint to be able to parse TypeScript code . We state that we are basically looking to create pretty new JavaScript code, EC MA version 2018.
[06:58 - 07:11] And in terms of a large number of ES Lint rules, we're going to extend an existing package or plugin known as TypeScript ES Lint recommended. And finally, we can customize the rules the way we see fit in our rules option right here.
[07:12 - 07:27] For now, we're simply turning off any indenting rules because prettier is going to take care of formatting for us. If we head to the code in our index.ts file, we can't be sure if our editor is actually picking up and showing any ES Lint errors.
[07:28 - 07:39] Well, currently at the moment of this screencast, the ES Lint VS code extension doesn't have TypeScript support enabled by default. And editor warnings are only being shown for JS files.
[07:40 - 07:49] To make this work, we'll need to add some form of information to our settings of our VS code editor. I'm going to be opening the settings JSON file in my editor.
[07:50 - 08:04] And I've already added in a block of code that we're going to need to add. Essentially, we need to specify that we want ES Lint to validate JavaScript code, JavaScript React code, TypeScript code, and TypeScript React code.
[08:05 - 08:18] We're adding in TypeScript React because we're going to be working with a Type Script React project very soon. You've set autofix to be true here, since this will allow for some autofix suggestions to be provided by the editor.
[08:19 - 08:35] Everything below some of my personal configuration, but everything above here from ES Lint validate is the actual field we need to be adding. In our instance, we still can't see any warnings or information from our editor .
[08:36 - 08:53] And we've realized this is because we've actually introduced a monorepo here called tinyhouse_v1 that contains another folder in which we want its ES Lint configuration to show up. We've noticed that the ES Lint extension in VS code doesn't behave very well in this scenario.
[08:54 - 09:14] So what we're going to do here is we're going to remove the import of the entire repository, tinyhouse_v1, and we're simply going to introduce the server folder from tiny house. And by doing so, we finally see some editor warnings thanks to our ES Lint extension.
[09:15 - 09:37] When we hover over one of the first two rules, we can see that this ES Lint warning tells us that type number is trivially inferred from a number literal, remove the type annotation. This rule is one of the ES Lint rules dictated from the recommended TypeScript package we're extending, and it basically states that simple types such as numbers, string, boolean, etc.
[09:38 - 09:59] can be easily inferred, so it doesn't have to be explicitly defined. We like this rule as a preference, so we'll comply and we'll remove the explicit definition that these variables are of the number type. Next, we hover over the function that returns the value for our get request.
[10:00 - 10:19] We can see that there's an ES Lint warning that tells us that this particular function misses a return type on the function. Just like how variables can be explicitly defined to have a type, functions in TypeScript can also be explicitly defined to have a type.
[10:20 - 10:38] Now as a preference, we prefer to follow the same format and say if variables can oftentimes be inferred from its type, we'll prefer if functions can just simply infer the type and only be explicitly defined if needed. So this is where we'll actually configure a rule in our ES Lint's RCH-JSON file .
[10:39 - 10:58] We're going to turn off one of the TypeScript ES Lint recommended rules from the package that we're actually extending. We're going to turn off the explicit function return type rule.
[10:59 - 11:12] When we head back to see the function, we can see that ES Lint doesn't actually give us a warning any longer since we've actually disabled that rule, and we're okay with doing so since that function type is being inferred. There's one more thing we're going to look at.
[11:13 - 11:22] When we actually hover over this request parameter in our callback function, we can see that VS code is actually giving us a warning. This isn't an ES Lint rule.
[11:23 - 11:32] This is a VS code TypeScript warning that we've actually ignored. And it's basically telling us that this request parameter is being declared but its values never being read.
[11:33 - 11:40] This is a useful warning, but in our particular case, we have to do this. This is because we have to access the second parameter, the response parameter.
[11:41 - 11:56] So even though we're not using the request parameter, we have to define it first. To notify TypeScript that we're aware of this, but we're okay with ignoring it, we can actually prefix this argument here with an underscore.
[11:57 - 12:08] This brings us to the end of this lesson, and we won't actually be making any more changes to our Linting rules in our server. There's one more important thing we should discuss before we close this lesson.
[12:09 - 12:23] When we hover over variables, parameters, functions, and when we actually see information that our editor tells us, this falls under a general bucket term that VS code calls called IntelliSense. And we mentioned this before.
[12:24 - 12:49] This feature that VS code offers is a very powerful feature, especially powerful when working with a good ES Lint setting and when working within a TypeScript development environment. Because not only are we able to hover and recognize issues and warnings, we're able to hover and also recognize the types that are being inferred for all the different variables, parameters, functions that can be used within an application.
[12:50 - 13:14] This development environment is especially powerful and especially cool in particular when you start to introduce more and more features into an app. If you've never had the chance to work within a development environment like this, I highly encourage you to come into the open mind because you may realize how much you actually enjoy building an application as things get more and more complicated thanks to the power VS code gives us.