Understanding lib and target in TypeScript Configuration
In this lesson, we will be investigating two important options in TypeScript: lib
and target
.
The lib
option lets you specify which JavaScript features are available in your environment. For example, ES2022
means all the JavaScript features that were in ECMAScript 2022 and its predecessors
Transcript
00:00 I want to talk about lib and target. Lib basically lets you specify which JavaScript features are available in the environment that you're operating in. So we have lib here being set to ES 2022, which means all of the JavaScript features that were in ECMAScript 2022 and earlier. Then we have the ones in the DOM
00:19 and the ones in DOM.iterable. But we can set target to something different from this. It doesn't have to be synced between lib and target. So we can say that when we transpile our TypeScript, we want to actually put it in this old syntax, ES5,
00:37 ancient, ancient syntax that most browsers, well, all browsers support now, and you could choose something different. You could choose ES 2017 or something. But you might think then that this is fantastic because TypeScript would just go in, polyfill all the code that needs to be moved down to ES5,
00:56 and it will just work. But TypeScript actually doesn't work that way. If we look at some code here, we've got two types of things that we want to be, they call it down-leveling, right? So moving to the previous era of JavaScript. So we want to down-level string.replaceAll. We want to say when we use this, actually polyfill a replacement for us
01:16 and actually make it work in ES5. A lot of bundlers will do this for you very cleverly. And we also want to say that when we use something like optional chaining or nullish coalescing, features that were added to JavaScript way after ES5, down-level those as well, make sure they work with ES5.
01:35 Now, let's look at the compiled JavaScript. When we look at this, we can see that the actual stuff to do with APIs, to do with things that you can have a reference to, like string.replaceAll, are actually not transformed and polyfilled by TypeScript. They're just used. This means that you're going to need
01:53 to find your own polyfills for those functions, string.replaceAll. Of course, there are many, many out there, but TypeScript won't by default transform the code for you. But the syntax is transformed. So any syntactical things like using, which came to TypeScript 5.2, optional chaining, nullish coalescing,
02:12 any of this stuff, decorators too, TypeScript will transform that syntax for you. So you need to think that TypeScript, when it's operating like this, is really just a syntax transformation device. It's just going to look at optional chaining and think, oh, okay, right. Sure, you use the question mark dot.
02:30 So I'm going to transform that into a check that means it actually sort of works. I mean, this code is pretty hard to read, but you never need to interact with this really as an end user or in a debugger or anything. Then the nullish coalescing here is doing exactly the same thing, sort of doing a similar sort of check, checking if search is not equal to null,
02:49 checking if it's not equal to void zero, amazingly, and then returning search. So there we go. This is the difference when you have lib and target set to different values really, is that TypeScript will transform syntax, but it won't transform the APIs. And in general, when you're doing this,
03:07 you probably want to set target and lib to the same value. You probably just want target ES 2022, lib ES 2022. And you want these values to be relatively in sync. So when you just want old features, let's say, then you're going to get an error when you actually try to use string.replaceAll without this. And it says here,
03:26 try changing the lib compiler option to ES 2021 and later. So there we go. Target and lib should probably stay in sync unless you're doing something interesting with actually polyfilling old APIs manually yourself and just using it to transform the syntax. But up to you, I would generally keep them in sync.