TypeScript and tsconfig.json

TypeScript and tsconfig.json

This article explains TypeScript and tsconfig.json.

Starting from the basic role of TypeScript, we will explain, with specific examples, how tsconfig.json functions within a project.

YouTube Video

TypeScript and tsconfig.json

TypeScript is 'JavaScript with types.'. However, to utilize TypeScript effectively in real-world projects, it is essential to understand tsconfig.json correctly and configure it intentionally.

Why do we need TypeScript?

First, the main reason for using TypeScript is 'the ability to catch mistakes before execution.'.

1function add(a: number, b: number): number {
2  return a + b;
3}
4
5add(1, "2");

This code would not cause an error in JavaScript until runtime, but in TypeScript it results in a type error at compile time.

This 'early detection' greatly improves development efficiency and quality.

How is TypeScript executed?

In principle, TypeScript cannot be executed as is. You need to convert it to JavaScript using the tsc (TypeScript Compiler)..

1npm install -D typescript
2npx tsc --init
  • By performing this operation, tsconfig.json is generated, providing the central file that defines the behavior of the TypeScript project.

What is the role of tsconfig.json?

tsconfig.json is a configuration file that determines 'which files,' 'with what rules,' and 'how to convert them.'. Although it may seem complex at first, only a few settings are truly important.

1{
2  "compilerOptions": {
3    "target": "ES2020",
4    "module": "ESNext",
5    "strict": true
6  }
7}
  • With just these settings, modern and safe TypeScript development is possible.

target: The version of JavaScript to output

target determines the specification level of the output JavaScript.

1"target": "ES2020"

With this, TypeScript will output JavaScript equivalent to ES2020. For older environments, select ES5; for only the latest environments, choose ES2022, etc.

When specifying ESNext

1"target": "ESNext"
  • ESNext specifies to output the latest available JavaScript syntax as is. TypeScript does not transpile the syntax, and instead leaves it up to the runtime environment such as Node.js or browsers to handle it.

  • Therefore, ESNext is suitable when targeting only the latest Node.js or when you're using Babel or a bundler to transpile separately. On the other hand, if the runtime environment does not support the latest syntax, this may result in runtime errors, so caution is needed.

module: Specify the module format

module specifies the module format.

1"module": "ESNext"
  • ESNext is the standard in the frontend and modern Node.js environments.
  • Choose "CommonJS" only if you need CommonJS.

strict: Maximize type safety

strict is a switch to maximize TypeScript's safety.

1"strict": true
  • Enabling this will thoroughly catch ambiguous types and potential bugs.

strict mode and implicit any

When you enable strict, TypeScript treats variables where the type cannot be inferred as an error.

1function printValue(value) {
2	console.log(value);
3}
  • This variable value does not have type information at declaration, so TypeScript cannot determine its type. As a result, any is used implicitly, which will trigger a warning (error) in strict mode.
1function printValue(value: number) {
2	console.log(value);
3}
  • By explicitly specifying the type like this, TypeScript can understand that 'this variable only handles numbers.'. In TypeScript, it is more important that the type can be uniquely determined than that the type can be omitted.

include/exclude: Controlling which files to compile

In tsconfig.json, you can specify which files to include and which files to exclude from compilation.

1{
2  "include": ["src"],
3  "exclude": ["node_modules"]
4}
  • With this, only the files under src will be managed by TypeScript.
  • node_modules specified in exclude will be excluded from compilation even if it's under a path included by include.

outDir: Specify the output directory

Specify outDir to manage your build output location.

1"outDir": "dist"
  • With this, all compiled results will be output to the dist folder. In practice, separating source code from build artifacts is standard.

rootDir: Specify the source directory

rootDir specifies the directory that TypeScript treats as the root of the source code.

1"rootDir": "src"
  • This setting allows TypeScript to preserve the directory structure based on src when outputting files. For example, src/index.ts will be output as dist/index.js.

  • The structure of the directory specified in rootDir will be replicated in outDir.

esModuleInterop: Bridging CommonJS and ES Modules

Next, let's look at esModuleInterop.

1"esModuleInterop": true
  • If enabled, you can safely use CommonJS modules with the import syntax.
1import fs from "fs";
  • This setting is almost essential when using Node.js.

noImplicitAny: Ban implicit 'any' types

It is also important to strengthen type checks in tsconfig.json.

1"noImplicitAny": true
  • With this, you can ban implicit any types. This allows you to reliably detect spots where you forgot to specify a type.

Configuration for detecting unused code

Settings for detecting unused code are also helpful for improving maintainability.

1"noUnusedLocals": true,
2"noUnusedParameters": true
  • With this, unnecessary variables and arguments are immediately flagged with warnings.

lib: Define the built-in APIs available for use

lib is a setting that specifies the standard APIs TypeScript assumes to exist.

1"lib": ["ES2020", "DOM"]
  • With this setting, the following types become available:. With ES2020, modern features such as Promise, Map, and Set become available. With DOM, browser APIs such as document, window, and HTMLElement become available.

In the frontend, include DOM; for Node.js-only projects, remove DOM to prevent unnecessary global types from being included.

moduleResolution: Module lookup rules

moduleResolution determines how modules specified in import statements are resolved.

1"moduleResolution": "Node"

The two main options are as follows:.

  • If you specify Node, the Node.js module resolution rules are used.
  • Classic is the old, TypeScript-specific method, but it is rarely used today.

In environments using Node.js or a bundler, it is safe to explicitly specify Node.

A minimal, production-ready tsconfig.json

Based on what we've covered so far, a minimal, production-ready tsconfig.json would look like this:.

 1{
 2  "compilerOptions": {
 3    "target": "ES2020",
 4    "module": "ESNext",
 5    "moduleResolution": "Node",
 6    "lib": ["ES2020", "DOM"],
 7    "strict": true,
 8    "rootDir": "src",
 9    "outDir": "dist",
10    "esModuleInterop": true,
11    "noImplicitAny": true,
12    "noUnusedLocals": true,
13    "noUnusedParameters": true
14  },
15  "include": ["src"]
16}

This configuration provides a safe foundation for both frontend and Node.js projects.

Summary: tsconfig.json is a 'rulebook'

tsconfig.json is not just a configuration file, but a 'rulebook' that applies to the entire project. With tsconfig.json, important policies like the following are clearly defined:.

  • The level of type safety.
  • Coding conventions for your team.
  • Prevention of future bugs.

By understanding tsconfig.json, you will be able to not only write TypeScript, but also design your projects for safe TypeScript usage.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video