A TypeScript tale - How to setup and configure
Tags: react, typescript, javascript, howto
Published: 2020-01-16 15:03:16

---
title: A TypeScript tale - How to setup and configure
published: true
date: 2019-10-08 15:26:24 UTC
tags: reactjs, typescript, javascript, how to
canonical_url: https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure
---

Table of contents:

- How do we install TypeScript?, [go to canonical section](https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure#how_do_we_install_typescript)
- Visual Studio Code & TypeScript = perfect marriage, [go to canonical section](https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure#visual_studio_code_typescript_perfect_marriage)
- Tooling and Configuration, [go to canonical section](https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure#tooling_and_configuration)
- Should I use a linter?, [go to canonical section](https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure#should_i_use_a_linter)
- Our first TypeScript code, [go to canonical section](https://www.reactgraphql.academy/react/a-typescript-tale-how-to-set-it-up-and-configure#our_first_typescript_code)

One of the mistakes I’ve made when I started with TypeScript was not to bother seeing what tools were available so that I could do a proper installation. Although I had my TypeScript project up and running very quickly, in the long run, this approach not only slowed me down because my configuration was not up to standard, but also made my experience less enjoyable.

We’ll have time to dig into syntax features, design patterns and so on. But for now, let’s get started by simply installing TypeScript on our machine.

## How do we install TypeScript?

**TypeScript compiler** : Despite what we may think, TypeScript does not reach the browser. It makes use of its compiler to search for errors. Only when they are all fixed are we allowed to successfully compile. And what does it compile to? JavaScript. JavaScript will get to the browser after our beautiful TypeScript is stripped out from our code.

Modern IDEs support TypeScript but usually do not include the needed compiler. We’ll need to install it separately.

- **Installing the TypeScript compiler globally:**

```
npm install -g typescript
```

_Note: If you’re on MacOS and get an “Eaccess” error, try sudo before the npm command._

- **Create a folder for your project and open it:**

You can either use the MacOS Terminal, the Windows Command Line or your IDE, but I’ll use the MacOS Terminal)

```
mkdir my-first-typescript-project && cd my-first-typescript-project
```

- **Create a file and name it index.ts:**

\*.ts is the official extension for TypeScript files and should be always used. It actually stands for TypeScript.

```
touch index.ts
```

- **Open your IDE of choice:**

First, you’ll want to make sure it supports Typescript. You might need to install additional plugin(s). Type the following line in your index.ts:

```
console.log(“Hello World”)
```

At this point, your code hasn’t been compiled to JavaScript yet, therefore your browser won’t be able to read it.

- **In your terminal, type:**

```
tsc index.ts
```

_Note: If you get an error when running the “tsc” command, it means something went wrong with your installation._

Now look at your file structure and you’ll find a new file _index.js_. This is the compiled file from your TypeScript. At the moment is identical since both syntaxes for this code are the same. Later on, we will see a slightly more complex example in which the JavaScript and TypeScript are different.

 ![](https://www.reactgraphql.academy/static/e3d623dd40f4f61cbcd5f89d32907f75c0e229be-468x98-580430fa61d269272ea10b7ec0ceaaf6.png)

## Visual Studio Code & TypeScript = perfect marriage

VS Code is created and maintained by Microsoft. Whilst there are many other options available such as Atom (GitHub) and Brackets (Adobe), VS Code made is way up to the top very rapidly. Its integration with TypeScript is phenomenal. There are many features making this happen but I’d like to highlight just a few of them I find important:

- **IntelliSense**  
IntelliSense shows you intelligent code completion, hover info, and signature information so that you can write code more quickly and correctly.

 ![](https://www.reactgraphql.academy/static/6800f41ff1ec69d6191cc54138d9a7b771c54b1c-1780x441-b3ad4e2f89f943ed0e14c73359425889.png)

- **Hover information**  
Hover over a TypeScript symbol to quickly see its type information and relevant documentation.

 ![](https://www.reactgraphql.academy/static/ae5c34dda17bcd9a29992724f234693130b626ac-1210x378-c173703eb198cd75fd5ab78735f1396f.png)

- **Signature help**  
As you write a TypeScript function call, VS Code shows information about the function signature and highlights the parameter that you are currently completing.

 ![](https://www.reactgraphql.academy/static/62441fc9390a3f43324837d5984853ebf14524ae-1206x362-beb0d9958ff02f08d78222e39086d70b.png)

- **Error checking**  
TypeScript main purpose is to warn you about programming mistakes through type checking. If you assign the wrong type, VS Code will throw an error message.

 ![](https://www.reactgraphql.academy/static/bcfdb3f03679635074cb361ebf67bab6819becfd-1200x318-5720f6bc2d24574c67aca52d096e14a4.png)

- **Quick fixes**  
VS Code runs a set of diagnostics to find coding issues and, in some cases, will give you powerful hints on how to fix the problem.

 ![](https://www.reactgraphql.academy/static/2fd8f4cc8fa8fde544146a69ac6a028c0aa605dc-1278x382-adc40a1eb676ab77cd9b1ae1f2dd79d2.png)

To install VS Code simply go to [https://code.visualstudio.com/](https://code.visualstudio.com/) and follow the instructions.

VS Code includes TypeScript support but does not include the TypeScript _tsc_ compiler. We’ll need to install it anyway.

## Tooling and Configuration

So far we’ve got a file and an IDE and we’re able to write and compile TypeScript code, which is great. But in a real-world scenario, you might want to customize your compiler. With this, you’re able to be almost as restrictive as you wish and enforce the right amount of coverage in your TypeScript code.

Also, this can be done incrementally simply changing your options. This is an action that takes time and much practice.

_tsconfig.json_ as the name suggests is a JSON format file where you can explicitly select and config your compiler options. It should be placed in the root folder determining this folder as the root of the project. To create we simply write in our terminal:

```
tsc --init
```

This command will create our _tsconfig.json_ with a json object called “compilerOptions”. Nested in it, we’ll have a few dozens of commented code lines leaving us instructions and tips for options that we can choose from.

For a basic setup we’d need just a few options:

```
{
    "compilerOptions": {
        "target": "es5" /* Specify ECMAScript target version */,
        "module": "commonjs" /* Specify module code generation */
    },
}
```

Our preferences might change from project to project and, especially, if we are using libraries or frameworks. In my case, I’m a React developer so these are some of the options I consider important in my projects:

- **--allowJs** : Allows JavaScript files to be compiled. This option can be quite useful when migrating a JS project to TS. It allows refactoring the codebase incrementally instead of all at one go. Developers who are not comfortable with TS might make use of this option also in greenfield projects when coming across with difficulties but is this something that’d add value to the project? My rule of thumb for this is not to allow JS compilation. Developers facing issues with TS might get too comfortable when there’s a “cheating” option and, in the long run, it won’t help the project to be consistent.
- **--checkJs** : This option follows a Blacklist approach where the compiler checks every JavaScript file by default. To use in conjunction with **--allowJs**.
- **--jsx** : This flag will allow to support \*._tsx_ and is shipped with three modes:
  - “preserve”: this mode will keep jsx as part of the output to be further consumed by another transform step (e.g. _Babel_). The output will have a \*._jsx_ extension.
  - “react”: this mode does not need to go through a JSX transformation before use and the output will have a \*._js_ file extension.
  - “react-native”: It’s the equivalent of “preserve” but the output will instead have a \*._js_ file extension.
- **--outDir** : Redirect output structure to the directory.
- **--rootDir** : Specifies the root directory of input files.
- **--forceConsistentCasingInFileNames** : Pretty self-explanatory. It disallows inconsistently-cased references to the same file.
- **--strict** : Enable all strict type-checking options.
- **--noImplicitAny** : The _any_ type should be a helper when in doubt but not a long term solution. And never to be shipped into production. With this flag set to true, we make sure the compiler will raise an error on expressions and declarations with an implied _any_ type.
- **--sctrictNullChecks** : In this mode, the _null_ and _undefined_ values are not in the domain of every type and are only assignable to themselves and the _any_ type. In the example below, we see that the parameter _firstName_ is optional. Therefore, there’s the chance of being undefined.

 ![](https://www.reactgraphql.academy/static/8ccab3adf5b75c45ab3aadd0490e271775b6f47d-1292x306-79df3f0835753806581e5ca2685def75.png)

This can be a problem in case we try to access this property. Being strict with this rule may prevent runtime errors when we try to access a property that is undefined

- **--esModuleInterop** : TypeScript can be quite fancy when importing modules depending on his specificity. In order to write a simple import statement such as:

```
import foo from “foo”
```

we need to set this flag to true.

## Should I use a linter?

In one word: yes. Linting is the action of statically analyzing code to detect programming errors. It comes back from the 70’s and it has been a vital part of any serious project, especially when is collaborative.

The linter defines rules or expectations about how our code should look like and It will flag any errors detected. Some of the benefits are:

- It turns our codebase more reliable and error-free.
- It makes the code more readable.
- It finds syntax errors before execution.
- Enforces better practices.

### ESlint vs TSlint
 ![](https://www.reactgraphql.academy/static/410088b50f86fab4baceeb1064dfb84f22eafd97-1600x1066-198a969a768ea95ef319128d0852393e.jpg)

Since its first release in 2013, [ESlint](https://eslint.org/) has been the standard for JavaScript linters.

> A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript

[TSlint](https://palantir.github.io/tslint/) came upon the scene being the obvious linting option for TypeScript. It’s a linter that can only be used for TypeScript, while ESLint supports both JavaScript and TypeScript. Since a big part of the community uses ESlint, TSlint revealed itself a barrier for many developers who use the former. Also, TypeScript caused surprise in the community when in their [2019 Roadmap](https://github.com/Microsoft/TypeScript/issues/29288#developer-productivity-tools-and-integration) announced their team will be focusing on leveraging ESLint instead of TSlint. It doesn’t mean the latter will go away soon but it’s a clear sign where the TypeScript team wants to go and where the community will be following it to.

Before we install any dependencies we need to create our _package.json_ file:

```
npm init
```

Then, to run ESlint, we’ll need to install the following:

- **eslint** : core library.
- **@typescript-eslint/eslint-plugin** : parser that will allow eslint to lint TypeScript code when running in conjunction with @typescript-eslint/parser.
- **@typescript-eslint/parser** : An ESLint-specific parser.

In our terminal we’ll type:

```
npm install eslint @typescript-eslint/eslint-plugin \
    @typescript-eslint/parser --save-dev
```

Now that we’ve got our dependencies installed, let’s create a _eslintrc.js_ (we can also use a json) file that we’ll use to set our rules. This file should be in the root, at the same level as the previously installed _tsconfig.js_:

```
module.exports = {
  parser: “@typescript-eslint/parser”,
  extends: [
    “plugin:@typescript-eslint/recommended”, 
  ],
 parserOptions: {
    ecmaVersion: 2018, 
    sourceType: 'module',
  },
  rules: {
     //Our ESlint rules. 
  },
};
```

The configuration above is a simple one that will get us ready to start writing awesome code. But ESlint wouldn’t be that useful without setting its rules. A list of rules can be found at [https://eslint.org/docs/rules/](https://eslint.org/docs/rules/).

## Our first TypeScript code

Let’s start by understanding the difference between a simple function expression in JavaScript and TypeScript.

```
const name = "Francisco";
const age = 36;
const human = true;

const character = (name, age, human) => {
  console.log(`
  My name is ${name}
  My age is ${age}
  Am I a human? ${human}
  `);
};
```

We can say the above function expression “character” accepts the arguments _name_, _age_ and _hero_. But what are its types? We can pass any type since there are no restrictions or documentation whatsoever.

Now let’s see the same code in TypeScript:

```
const name = "Francisco";
const age = 36;
const human = true;

const character = (name: string, age: number, human: boolean): void => {
  console.log(`
  My name is ${name}
  My age is ${age}
  Am I a human? ${human}
  `);
};
```

In case you get an error like this:

 ![](https://www.reactgraphql.academy/static/fbfc057211a717bb11128eaa92da4b54d2e4a4f1-646x242-255ee4b7a29f019fadad41c674d6ac6d.png)

There’s a very short and nice article [here](https://medium.com/@muravitskiy.mail/cannot-redeclare-block-scoped-variable-varname-how-to-fix-b1c3d9cc8206) about why it happens and how to fix it.

In this last block, we explicitly say name is a _string_, age is a _number_ and hero is a _boolean_. Since we don’t return anything, we use the type void which is used where there is no data type. These are called type annotations. Try this code in your _index.ts_ file.

Now, and just for fun, try to run:

```
tsc index.ts
```

Open the corresponding JavaScript file to compare the code.

```
var name = "Francisco";
var age = 36;
var human = true;

var character = function (name, age, human) {
    console.log(`
        My name is ${name}
        My age is ${age}
        Am I a human? ${human}
    `);
};
```

Notice anything different? Among other details, there are no template literal strings and our _const_ are now var.

But what’s important to notice is that the type annotations have disappeared. They’ll not be read by the browser.

This episode is over and now we have our machine ready to write beautiful TypeScript. Next, we’ll have a look at types and consider some other advantages of using a type system.

#### Related articles

Previous: [A TypeScript Tale - Episode 1](https://www.reactgraphql.academy/react/a-typescript-tale-episode-1/)

Next:

[A TypeScript Tale - The almighty types](https://www.reactgraphql.academy/react/a-typescript-tale-3-the-almighty-types/)

[A TypeScript tale - Interfaces, Classes & Generics](https://www.reactgraphql.academy/react/a-typescript-tale-interfaces-classes-and-generics/)