Check out a free preview of the full Enterprise TypeScript course
The "Install TypeScript & Configure tsconfig.json" Lesson is part of the full, Enterprise TypeScript course featured in this preview video. Here's what you'd learn in this lesson:
Mike installs the TypeScript compiler and creates a tsconfig.json file. The available configuration options are examined and TypeScript is configured for all files in the src directory and the .eslintrc.js file.
Transcript from the "Install TypeScript & Configure tsconfig.json" Lesson
[00:00:00]
>> Next, we're going to install the TypeScript compiler, so here we go. Yarn add -D for devDependency, typescript@5.3.0-beta. What I would prefer you do if you're doing this at home, and it's later than the recording, I would want you to do something like this. ~5.3.0, that'll get you the latest TypeScript 5.3.
[00:00:31]
We're explicitly specifying this just cuz we're using this. I expect 5.3 to be cut like next week as a stable release. So this is a very refined beta. Great, and we can see evidence that it was installed right here. Okay, so we have TypeScript installed. Now, we need a tsconfig file, right.
[00:00:54]
This is what we use to configure. How TypeScript compiles our code. And this is another big JSON file that if we were to create it by hand, we certain could. But if you've done this enough that you've memorized all of the different keys that you wanna apply, maybe you do that.
[00:01:14]
Here's what I tend to do, yarn tsc --init, this is what I was getting --init from. You run that And here's your output here. It said it created a new tsconfig with, and then a bunch of different settings here. And it gives you a link where you can learn more about tsconfig.
[00:01:40]
I saw a reaction in class that this seems to be it.
>> I was just surprised by it not only filled in those defaults. But every other possible compiler option with a comment about what that compiler option does. It was just a surprise is all.
>> It's a surprise.
[00:01:57]
So, for one it's a lot in this file. If you're just starting out with TypeScript or it's nice to have the comments here. This isn't adding any weight to your project. It does, every single option commented out lets you uncomment it. There are a couple things in here I don't like, and I'm gonna explain why I don't like them.
[00:02:20]
So we're gonna begin the process of going through and changing some of these things. And I've arranged these changes from top to bottom so you can just follow along with me. If you're looking on the course website, they're also arranged like section by section, right. So we're gonna start with the target property and move down from there.
[00:02:42]
So for the target this describes the target JavaScript language version. So a great way to think about this is like before ES2017, there was no async await. And that means TypeScript's build output. Will not use the async or await keyword. They'll have an elaborate polyfill that makes that code run as it should.
[00:03:05]
But it's not true async and await, as in you won't see that in the output code. So we're gonna bump this up to 2022. Next we're gonna go into this section called modules down here. And commonjs is what we want here for the modules. We're gonna define a rootDir.
[00:03:27]
And this is important because it affects auto imports a little bit and in effect, sort of If you were to publish this package. You don't wanna be like library name/source/module name. You just wanna be like library name/module name. So we're gonna make that change by saying, look, the src folder is where all my code is.
[00:03:51]
Next, we're going to uncomment this types array. Feel free to think that I'm a little OCD here. What we're saying here is we have to specify the type packages that are allowed in this project. Normally, you'd be able to access anything in your package JSON. If you have an at types package, which we'll talk about later, type information you download for a library that is written in JavaScript.
[00:04:18]
It doesn't publish its own types. Normally, you'd have access to everything in your package JSON. What I don't like about that is that, let's say we download the types for Jest, which we wanna use only in our tests. TypeScript will kinda let you import the Jest library in your live application like it's easy to sort of cross the wires there.
[00:04:44]
And being explicit about this like it can become unmanageable for projects with tons and tons of dependencies. But it's I like to at least start out with a library like this. Having very deliberate control over what my dependencies are. And that way, I don't sort of write the name of a function and then.
[00:05:03]
Not looking closely enough and I auto-import it, and it ends up being like something I just use for build or for tests. I don't necessarily want all of that to go along with my published code. The next thing we'll change it's in another section here in the emit section.
[00:05:20]
So this set of compiler options describes how TypeScript emits your code. Right, what ends up in that dist folder? We're going to enable declarations, which means our TypeScript source code will compile out to not only runnable JavaScript. But you'll get the types that represent that JavaScript side-by-side in the dist folder.
[00:05:49]
By default, you don't get these. You can opt in by enabling declaration true. We're gonna define the outDir. This is the build output Dir, and we're gonna make this dist. StripInternal is interesting. We'll talk more about this when we deal with something called API extractor. Which is super useful for libraries, we're going to deal with it in this project here.
[00:06:18]
You can add a JSDoc comment tag at internal to like a function for example. And what this does is it makes sure that anything you've marked as internal will be stripped out of the type declarations. This is useful because sometimes you wanna export a function and it's just there, maybe it's just there for testing purposes, right.
[00:06:43]
So that in your test harness, you can call into this thing and maybe it's sort of. I don't know, maybe you use a date in the function that's publicly called. And you want some inner part of that logic where you provide a date. So you can write a nice stable test that will not have the randomness of the now date in it.
[00:07:04]
But this will let you kind of expose things technically out of the package without them ending up in your declaration file. EsModuleInterop they have this set to true. Cuz their typed script wants to sort of get people moving towards the MGS, the ES module file format. I think this is an appropriate setting to leave enabled for an app.
[00:07:29]
For a leaf level dependency, meaning something that nothing else depends on. I tend to leave this false and it's because if you enable this in the library. And when you enable this, you're almost saying MyTypes normally would not work. They would not compile. But if I enable this flag, MyTypes will compile.
[00:07:54]
And what ends up happening is you generate types in many cases where anyone else who needs to compile their code. Which includes your types, if they depend on your library, they also must turn this flag on. And when I'm writing libraries, I don't like to force my consumers to change their tsconfig just to make my stuff work.
[00:08:16]
So I tend to leave this off for libraries specifically. Completeness, okay, I really don't know why they leave this set to true, by default. SkipLibCheck, let's look at what this is. It says skip type checking all .d.ts files. Effectively, if you leave this set to true. You will not, like, if there are type errors that appear in declaration files within your node modules folder, ignore those.
[00:08:49]
And that may seem not so harmful in the beginning, right. It's tempting when you see those those like type checking errors in your node modules folder. It's tempting to just wanna turn this on and say, well, if I turn this on, I won't get these errors anymore. But remember, type checking is a holistic operation.
[00:09:07]
You want the types in your code to work very nicely with types in library code. In the fundamentals, and intermediate TypeScript courses, we talked about different ways of structuring your code. Can make errors appear in different places. There are different ways of writing code. That sometimes it would make an error like a type checking error pop up in the node modules folder.
[00:09:28]
When really you need to adjust your app code in order to make it work. So I tried to leave this set to false, I don't like skipLibCheck for that reason. I want there to be no compile errors in this whole list of operation. Which includes MyTypes, my dependencies types, all of that ends up being the code that I ship to my users, right.
[00:09:54]
So I tend to leave this set to false. I want no errors anywhere if I can get away from it. You get away with it. I've never actually found a need to turn this on. If your node modules types are objecting to something, it could be a sign you're using a dependency realm.
[00:10:12]
One more section here that we kinda skipped over. But I wanted to do this last cuz it's kind of one of the more interesting ones, that type checking section. So this is where we're going to enable some nice strong type checking. As I would if I were writing a TypeScript library from scratch.
[00:10:32]
This is not my starting point, if I'm trying to convert a JavaScript code base to TypeScript. I start with a much less restrictive type checking configuration in that case. But here, we're just gonna enable a couple things that kind of make a lot of sense. So we'll enable no implicit and we'll talk about each of these in detail and what they do in the next chapter.
[00:10:55]
UseUnknownInCatchVariables we'll turn that on. No unused locals and parameters will turn that on. ExactOptionalPropertyTypes will turn that on. And then noImplicitReturns turn that on. I leave this one off like no fall through cases and switch. I think this is a taste thing I would never judge anyone for preferring to say I don't like fall through cases.
[00:11:26]
And switch meaning like a case clause where you don't have a break at the end of it. I consider that to be kind of like a feature. Sometimes you can design things that way. Some might argue that. You really have to look at all of the case clauses to make sure you understand what's going on.
[00:11:43]
But this is up to taste as far as I'm concerned noUncheckedIndexedAccess. NoImplicitOverride and noPropertyAccessFromIndexSignature. I left some of these unchecked because we could enable no implicit this as well. These things are included in strict. You could turn them on. It's not harmful but it's redundant. Strict covers those things.
[00:12:12]
You notice how they're the words that are the options starting with strict. It makes it easy to remember, it's very rare for new things like this to appear. I think this one was one of the more recent ones, which was TypeScript 2.8. That's like one of the last times they added something in strict mode.
[00:12:37]
So, like point being. If you enable this, it's like a pretty stable set of things, and a lot of the new options end up being like things you have to explicitly turn on. Always strict, this is not strict mode. This is JavaScript, use strict. But because of the type of modules we're outputting, it's implicitly strict mode.
[00:13:02]
There is no, we're saying ES 2022, like everything after ES 2015 must be using strict mode. You can't have classes unless you're in strict mode. It's this turning this on would mean you're writing some seriously, or disabling this. Would mean you're writing some really old Javascript for IE 10.
[00:13:29]
Let's add one more thing to the bottom here, and it's include. And this describes the code that we want to be type checked. So we'll add our src folder there cuz that's where our source code is gonna be. We're gonna add one more file here. We're gonna, we have an ESLintConfig that's gonna appear when we install our linter, and it's a JavaScript file.
[00:13:59]
And adding it here, because our ESLintConfig is gonna want to look at our TypeScript tsconfig, we should include it here. And once we have the ESLintConfig in place, I'll just, to show what happens, I'll delete this. And we'll see that it'll light up and say, I'm a JavaScript file, and I should be linted.
[00:14:21]
But I'm not in the js campaign.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops