An intro to TSConfig for JavaScript Developers
Tags: typescript, javascript, webdev, deno
Published: 2024-04-23 17:16:39

JavaScript is constantly evolving, from its roots as a simple scripting language into a robust, modern tool for building complex applications. To manage larger, complicated code bases, JavaScript developers are constantly looking for ways to improve their workflows, their code quality and productivity. TypeScript is a major innovation towards improving code quality and maintenance by adding types, so it’s no surprise that
[it’s one of the fastest growing languages](https://medium.com/@easycodingschool13/typescript-is-fastest-growing-programming-language-4c1ec9462ef8#:~:text=According%20to%20the%20JetBrains%20Status,growing%20programming%20language%20in%202022.).

TypeScript can feel scary if you've never used a compiled language or a compiler before. Or maybe you have, and you encountered a complex `tsconfig.json` file that you didn’t completely understand. This blog post is an introduction to TypeScript (TS) and how to configure your project to use TypeScript with ease:

- [From JS to TS](#from-js-to-ts)
- [TSConfig settings](#tsconfig-settings)
  - [`compilerOptions`](#compiler-settings-in-compileroptions)
  - [Other TSConfig settings](#other-tsconfig-settings)
- [Additional features and capabilities of TSConfig](#additional-features-and-capabilities-of-tsconfig)
- [What’s next](#whats-next)

> 🚨️ **Want to write and run TypeScript without any config?** 🚨️
>
> [Deno natively supports TypeScript.](https://deno.land/manual/advanced/typescript)
> Simply create a `.ts` file and run `deno run yourfile.ts`.

## From JS to TS

TypeScript is built on top of JavaScript. It's a superset — any valid JavaScript is valid TypeScript. If you're new to TypeScript, it's easy to think of it as a "super powered linter", adding new features to the language to help you write JavaScript safely. It is designed to be strictly additive — TypeScript with the types stripped out is just JavaScript, but with types present, you get a much improved tooling, debugging and general developer experience.

Because the JavaScript ecosystem has grown organically over time, TypeScript aims to fit in with your existing tooling. Modern editors, build tools, package managers, testing frameworks and CI/CD tools all integrate with TypeScript. In order to adopt TypeScript, and tailor it to your specific project requirements and tools, you will need to configure the TypeScript compiler. This can be done using a file called `tsconfig.json`.

If you're doing TypeScript for the first time in a new codebase, you will probably leave most of the options in `tsconfig.json` as default. For projects with tooling that needs interop, or has particular quirks, `tsconfig.json` offers all the leavers you may need to pull to interact with your ecosystem.

## TSConfig settings

The `tsconfig.json` file allows you to configure how the TypeScript compiler processes your TypeScript code. The `tsconfig.json` file is just a JSON object with properties that define your compiler options and project settings. We’ll go through some of the properties you’re likely to need when setting up your own `tsconfig.json` file.

The first property to take a look at is `compilerOptions`, where you specify compiler settings.

### Compiler settings in `compilerOptions`

The `compilerOptions` property is where you define TypeScript compiler settings.
These options include -

`target` - Specifies the ECMAScript target version for the emitted JavaScript. Defaults to ES3. To ensure maximum compatibility, set this to the lowest version that your code requires to run. `ESNext` setting allows you to target the [latest supported proposed features](https://github.com/tc39/proposals).

`module` - Defines the module system to use (`CommonJS`, `AMD`, `ES6`, etc.). Usage depends on your project’s requirements and the environment that your code will run in. Most modern projects will use `ES6` or `ESNext`.

`outDir` - Specifies the output directory for compiled JavaScript files. Usually set to `dist` to create a dist directory for your compiled files.

`strict` - Enables strict type-checking options to help catch errors in your code. Set to `true` for strict type checking.

`alwaysStrict` - Automatically set to `true` if `strict` is enabled, this parses the code in JavaScript strict mode and emits `use strict` for each source file.

`esModuleInterop` - In JavaScript, there are two main module systems: ECMAScript modules (ESM) and CommonJS modules (CJS). They have different syntax and semantics for imports and exports. When working in a TypeScript project that uses both ESM and CJS modules, setting `esModuleInterop` to `true` ensures that TypeScript handles imports and exports in a way that is compatible with both module systems. This is recommended if you are working with third party libraries that use both CJS and ESM.

`lib` - Specifies the libraries to include when type-checking. TypeScript includes type declarations (type definitions) for JavaScript built-in objects, such as Array, String, Promise, etc. These declarations define the shape and behavior of these objects, allowing TypeScript to provide accurate type checking and IntelliSense support. By default, TypeScript includes a standard set of library declarations (`dom`, `es5`, `es6`, etc.) based on the ECMAScript version targeted by your project. However, you can customize the included libraries using the "lib" option to match your project's environment more precisely. For example, if you're targeting only Node.js, you might exclude browser-specific declarations like `dom`.

`sourceMap` - Generates source map files (.map) to aid debugging. Source maps are files that map the generated JavaScript code back to its original TypeScript source code. When using debugging tools, source maps allow you to set breakpoints, inspect variables, and step through your TypeScript code as if you were debugging the original TypeScript source. Set to `true` to enable the use of source maps.

**Other settings that may be useful:**

`jsx` - If you are using JSX (for example with React), this setting determines [how your JSX files should be treated](https://github.com/microsoft/TypeScript-Handbook/blob/master/pages/JSX.md)(`preserve`, `react`, `react-native`, etc.).

`removeComments` - Strips comments from your compiled code. Helpful if minifying your compiled code.

`sourceRoot` - Specifies the location where your debugger should locate TypeScript files instead of source locations. Use this flag if the sources located at run-time are in a different location than that at design-time. The location specified will be embedded in the source map to direct your debugger.

### **Other TSConfig settings**

`include` - specifies an array of file paths or glob patterns that TypeScript should include in the compilation process. Only files matching the specified patterns will be considered for compilation. You can use glob patterns (e.g. "src/**/*.ts") to include files from specific directories or with specific file extensions. If include is not specified, TypeScript includes all `.ts`, `.tsx`, and `.d.ts` files in the project directory by default.

`exclude` - This setting specifies an array of file paths or glob patterns that TypeScript should exclude from the compilation process (even if they match the patterns specified in the **`include`** setting). You can use **`exclude`** to ignore files or directories that you don't want to be compiled, such as test files, build artifacts, or third-party libraries. Usually you will want to exclude your `node_modules` folder.

### **Additional features and capabilities of TSConfig**

**Declaration Maps** - TypeScript can generate declaration map files (`.d.ts.map`) alongside declaration files (`.d.ts`) if `declarationMap` is set to true in your `tsconfig.json`. Declaration maps serve a similar purpose to source maps but are specific to TypeScript declaration files. These declaration maps provide mappings between the generated declaration files and their corresponding source map files, aiding in debugging and providing better tooling support.

**Watch Mode** - TypeScript's watch mode `tsc --watch` monitors changes to your TypeScript files and automatically recompiles them whenever they're modified. This is useful during development, as it speeds up the feedback loop and eliminates the need to manually trigger compilation after each change.

**Incremental Builds** - TypeScript's incremental builds feature keeps track of changes to your project's files and dependencies, allowing it to only rebuild the parts of your project that have changed since the last compilation. This can improve compilation times for large projects.

**Override Options** - You can override specific compiler options for individual files or sets of files using comment directives in your TypeScript source files. For example, you can disable certain strict checks with `// @ts-ignore` or specify custom compiler options with`// @ts-nocheck` for specific sections of code.

Use your `tsconfig.json` tile as a gateway to unlock the full potential of TypeScript in your projects. By understanding its purpose and leveraging its capabilities, you can embrace TypeScript with confidence, and gain a more reliable, efficient, and enjoyable development experience.

**To get you started there is a [community owned repository of TSConfig base files](https://github.com/tsconfig/bases) for your chosen runtime**, then all you need to focus on is the unique choices for your project.

## What’s next?

More and more developers are using TypeScript to build higher quality code bases and be more productive. Hopefully, this post demystifies setting up a new TypeScript project using `tsconfig.json`.

However, if you’re interested in diving into TypeScript without having to do any configuration,
[Deno supports TypeScript natively](https://deno.land/manual/advanced/typescript). Simply create a `.ts` file, write some types, and run it immediately with
`deno run your_file.ts`.