Types You Don't Control 12 exercises
solution

Updating Node.ProcessEnv

There are two options for modifying the global scope in TypeScript: using declare global or creating a .d.ts declaration file.

For this solution, we'll create a process.d.ts file in the src directory.

In order to determine what to put in the file, we'll want to look at the type definition

Loading solution

Transcript

00:00 Okay, when we're adding types to the global scope, we've got two choices. We can either use a declare global, or we can add a .d.ts file. For this, I'm going to add a .d.ts called process. Now inside process, if we look back at our index.ts file, let's take a look at processenv.

00:17 We can see that nodejs.processenv is basically an interface sitting like inside the Node.js namespace. So if I command click on this, I can see that node.processenv is basically here, and it's an interface. So if I command click on there, we've got an interface here, nice. And if we zoom all the way up,

00:37 we can see that this is inside a namespace, inside a global. Okay, so now what we have is namespace Node.js, and we have an interface inside it. We know that these can declaration merge, right? So if we declare a new interface called namespace Node.js here,

00:57 then inside here, I think I'm going to have to add a declare in front of this too, so declare namespace Node.js. Inside here, I can add interface processenv, and then I can say myenv var is going to be a string. So if we look back at index.ts now,

01:17 I just bring these out to two separate files, pull this over so my face is not in the way, we can see that hovering over myenv var, it's now considered a string, and invariable is now a string too. If I mess this up, if I say myenv var two, for instance, then it's not going to be a string. And I actually get auto-complete for this too,

01:37 so I get myenv var two just there. Oh, beautiful. So now myenv var, which is the one I wanted, is now auto-completable on processenv and typed as a string. Now, this doesn't give you any runtime guarantees at all. This is not going to guarantee that myenv var is going to be a string at runtime,

01:56 so you have to be careful that you do, you're actually honoring that contract, really, inside your environment that you post it in. You could even, of course, just say if not invariable, throw a new error, like this, invariable not assigned, and then you wouldn't even need to do any of this, let's say, it would just,

02:16 sure, it's string or undefined up there, but by the time you actually access it, it's a string. So that's pretty safe too. But I do really like just having this auto-completable available to me, and it's just a more honest way of typing what your app is actually doing. You could, of course, just still have the same type safety, this could be string or undefined,

02:36 and then you still get access to all of the, still get access to the auto-complete as well, because it's the auto-complete that you really want, and this kind of extra string stuff is just a little bit of extra convenience that you probably would want to make sure is being checked somewhere in your application.

02:53 But this is a really cool pattern for overriding or kind of appending to the interface of Process Env inside the namespace of a different, an external library. And often you'll see this pattern occasionally when you're using external libraries, they want you to append to a global, they'll probably put that global

03:11 inside some sort of namespace just like this. So, really nice pattern to know about.