TypeScript: Getting Started With TSConfig Options

What is TypeScript? TypeScript is a superset of JavaScript. This means you can use JavaScript syntax in TypeScript, so learning JavaScript before jumping into TypeScript is best. With that disclaimer, let’s talk about what TypeScript is all about and how we can set up a project for TypeScript. According to the documentation for TypeScript, “TypeScript is a strongly typed programming language that builds on JavaScript.”[1] The TypeScript language adds type syntax to help you catch errors early during development and keeps safeguards up while your development team grows as a project scales. TypeScript allows you to define the datatypes for variables and interfaces for objects. TypeScript uses these definitions to check your code for errors as it compiles and informs you when you are not following the definitions you set beforehand. If you're thinking, "Why do I need to write more code just to use TypeScript when I can be more careful in the first place?" You're not wrong, but humans can make errors, and we often do when working for long periods. If this same thinking were applied to construction, then the additional scaffolding and safety procedures would require more work and time, and we can save time by just being careful at the work site. See? In an effort to save time, this roofer may have wasted more time and resources. This is just one worker. Imagine a team of workers working on a project as more team members are added. This is the reality of software development; having a plan to catch these mistakes will help you and your team in the long run. TypeScript Examples The following examples come from the TypeScript documentation[2], but the commentary is mine. TypeScript: function greet(person, date) { console.log(`Hello ${person}, today is ${date}!`); } greet("Brendan"); TypeScript will catch the error when greet is called. We defined greet to receive two arguments, person and date, and we only supplied person. TypeScript will catch this error when it compiles the code and lets you know it expected a second argument. In a way, TypeScript can be considered a linter for your code to catch these errors while you're working, but we can leverage the type syntax to help us further. function greet(person: string, date: Date) { console.log(`Hello ${person}, today is ${date.toDateString()}!`); } greet("Maddison", Date()); Now, we add a type to the two arguments, person must be a string, and date must be a Date object for the toDateString method. When greet is called without the keyword new before the second argument, Date(), TypeScript will let you know it received a string instead of a Date for the date parameter. Now, you can fix your error before developing further and having to trace back to this error when you receive an unexpected output while testing. Now that you've seen TypeScript in action let's examine the next steps in setting up your project to use it. Configuring TypeScript's Compiler: tsconfig.json The default TypeScript compiling may not be what you are looking for, and there is a way to customize TypeScript for your needs, similar to using a linter, but it can do so much more. The first step is to create a tsconfig.json file in your project's root directory. This file tells TypeScript which files should be included in the compilation process. In the tsconfig.json, you can specify the directories from the root that should be included if you want more specificity using your JSON file's "includes" key. { "include": ["src/**/*"] } Now, let's talk about "compilerOptions". Trust me when I say there are a ton of options to choose from. This is a good thing but also terrifying if this is your first time using TypeScript. I'm going to break down a few of the popular choices to help you get started: allowJs { "compilerOptions": { "allowJs": true } } This option allows JavaScript files to be imported inside your project instead of only TypeScript. Typically, TypeScript assumes all imports are TypeScript and would give an error for imported JavaScript files, but this option allows us to use those imports and can be helpful when working with TypeScript and JavaScript in the same repository. esModuleInterop { "compilerOptions": { "esModuleInterop": true } } A namespace import in ES6 can only be an object, but since this is the same as using require without .default, we have allowed TypeScript to treat an object as a function. Instead of having to be careful about our imports, this option will fix this issue when TypeScript transpiles the code into JavaScript. target { "compilerOptions": { "target": "es6" } } This option changes which JS features are downgraded and which are left intact when TypeScript transpiles your code into JavaScript. es6 is a good choice since most modern browsers support ES6, but you can designate any version of ECMAScript

Jan 13, 2025 - 06:45
 0
TypeScript: Getting Started With TSConfig Options

What is TypeScript?

TypeScript is a superset of JavaScript. This means you can use JavaScript syntax in TypeScript, so learning JavaScript before jumping into TypeScript is best. With that disclaimer, let’s talk about what TypeScript is all about and how we can set up a project for TypeScript.

According to the documentation for TypeScript, “TypeScript is a strongly typed programming language that builds on JavaScript.”[1] The TypeScript language adds type syntax to help you catch errors early during development and keeps safeguards up while your development team grows as a project scales. TypeScript allows you to define the datatypes for variables and interfaces for objects. TypeScript uses these definitions to check your code for errors as it compiles and informs you when you are not following the definitions you set beforehand.

If you're thinking, "Why do I need to write more code just to use TypeScript when I can be more careful in the first place?" You're not wrong, but humans can make errors, and we often do when working for long periods. If this same thinking were applied to construction, then the additional scaffolding and safety procedures would require more work and time, and we can save time by just being careful at the work site.

Roofer tries to carry roofing materials up a ladder by themselves without scaffolding put up or safety equipment on, and they drop the roofing materials, knock the ladder over, and fall off the roof with the roofing material landing on top of them. The roofer does get up at the end of the GIF.

See? In an effort to save time, this roofer may have wasted more time and resources. This is just one worker. Imagine a team of workers working on a project as more team members are added. This is the reality of software development; having a plan to catch these mistakes will help you and your team in the long run.

TypeScript Examples

The following examples come from the TypeScript documentation[2], but the commentary is mine.

TypeScript:

function greet(person, date) {
  console.log(`Hello ${person}, today is ${date}!`);
}

greet("Brendan");

TypeScript will catch the error when greet is called. We defined greet to receive two arguments, person and date, and we only supplied person. TypeScript will catch this error when it compiles the code and lets you know it expected a second argument. In a way, TypeScript can be considered a linter for your code to catch these errors while you're working, but we can leverage the type syntax to help us further.

function greet(person: string, date: Date) {
  console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}

greet("Maddison", Date());

Now, we add a type to the two arguments, person must be a string, and date must be a Date object for the toDateString method. When greet is called without the keyword new before the second argument, Date(), TypeScript will let you know it received a string instead of a Date for the date parameter. Now, you can fix your error before developing further and having to trace back to this error when you receive an unexpected output while testing.

Now that you've seen TypeScript in action let's examine the next steps in setting up your project to use it.

Configuring TypeScript's Compiler: tsconfig.json

The default TypeScript compiling may not be what you are looking for, and there is a way to customize TypeScript for your needs, similar to using a linter, but it can do so much more.

The first step is to create a tsconfig.json file in your project's root directory. This file tells TypeScript which files should be included in the compilation process. In the tsconfig.json, you can specify the directories from the root that should be included if you want more specificity using your JSON file's "includes" key.

{
  "include": ["src/**/*"]
}

Now, let's talk about "compilerOptions". Trust me when I say there are a ton of options to choose from. This is a good thing but also terrifying if this is your first time using TypeScript. I'm going to break down a few of the popular choices to help you get started:

allowJs

{
  "compilerOptions": {
    "allowJs": true
  }
}

This option allows JavaScript files to be imported inside your project instead of only TypeScript. Typically, TypeScript assumes all imports are TypeScript and would give an error for imported JavaScript files, but this option allows us to use those imports and can be helpful when working with TypeScript and JavaScript in the same repository.

esModuleInterop

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

A namespace import in ES6 can only be an object, but since this is the same as using require without .default, we have allowed TypeScript to treat an object as a function. Instead of having to be careful about our imports, this option will fix this issue when TypeScript transpiles the code into JavaScript.

target

{
  "compilerOptions": {
    "target": "es6"
  }
}

This option changes which JS features are downgraded and which are left intact when TypeScript transpiles your code into JavaScript. es6 is a good choice since most modern browsers support ES6, but you can designate any version of ECMAScript for this option to suit your needs.

strict

{
  "compilerOptions": {
    "strict": true
  }
}

This flag enables many different type checking behaviors. This will result in a stronger codebase with fewer errors. If you like to exclude certain type checking behaviors, check the documentation [3] and set their options to false. If you only want a couple type checking behaviors, I would consider turn those on instead of using strict.

outDir

{
  "compilerOptions": {
    "outDir": "./dist"
  }
}

When TypeScript transpiles your code into usable JavaScript, this option will emit those files into this directory.

noEmit

{
  "compilerOptions": {
    "noEmit": true
  }
}

This option stops all transpiled JavaScript files from emitting. This may sound silly since I just told you about outDir, but TypeScript will always emit files and outDir will direct the files to the correct location. noEmit comes into play when you are already using another tool like Babel or Webpack to transpile and bundle your code. Emitting in this case would mean creating useless JavaScript files.

Conclusion

There you have it. Those are seven options to help you set up your configuration for TypeScript and how TypeScript can help you create a more stable code base. I recommend giving Matt Pocock's "The TSConfig Cheat Sheet" a read for more popular options to put in your tsconfig.json and always refer to the TypeScript documentation on the TSConfig before implementing any of these options.

Happy Coding!
Tyler Meyer

Sources:

[1] https://www.typescriptlang.org/

[2] https://www.typescriptlang.org/docs/handbook/2/basic-types.html

[3] https://www.typescriptlang.org/tsconfig/

[4] https://www.totaltypescript.com/tsconfig-cheat-sheet