Check out a free preview of the full Intermediate TypeScript, v2 course:
The "Top Types" Lesson is part of the full, Intermediate TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Mike discusses extreme types in TypeScript, specifically the top and bottom types. The top type, "any", can accept any value and is often used when TypeScript cannot infer a more specific type. The top type, "unknown", requires type narrowing before it can be used.

Get Unlimited Access Now

Transcript from the "Top Types" Lesson

[00:00:00]
>> Extreme types, these are types that accept anything or almost anything, and types that accept nothing or almost nothing. And we call these, respectively, top and bottom types. So TypeScript has a wide range of things that sort of fit into this extreme types category. And by the end of this chapter you should understand like what these things are.

[00:00:24] Some pragmatic use cases for where some of these different things are best applied. And in particular there's a really cool pattern around the use of the Never type, which is tops scripts bottom type. This is called exhaustive conditionals, and it's one of my favorite things, favorite patterns to use in TypeScript.

[00:00:47] So we'll get a little bit into that. So first, I'm actually gonna pivot to my VS Code, which you can follow on in the website if you like. The first thing we're gonna talk about is the type any. So we've been dealing with this already, you see a lot of anys particularly as you're starting to use TypeScript, even more so if you're converting a JavaScript code base to TypeScript a lot of things start out as these implicit any's, or typeScript cannot infer a more specific type.

[00:01:19] But any can accept anything, that's what makes it a top type, can accept anything. Any value you can create in JavaScript, you can put in a variable of type any. So here we can see I've got something I'm initially assigning it a number, then I'm putting a string in there, then the window.document object, then the function settimeout, type scripts, happy to let me do this.

[00:01:45] But I want you to think about this as sort of type checking being disabled. We just got done talking about this at the end of the declaration merging chapter where somebody asked, I had this sort of empty object as any. And I said, well, I'm putting the any there so that TypeScript is not actually caring at all about the specifics of like comparing the types to things.

[00:02:07] That's exactly what we're seeing here. TypeScript has sort of backed off and regular JavaScript rules apply, which is, of course, a problem here. Look at this almost sentence that I'm able to write. Obviously, none of these objects are here, and TypeScript is not doing a thing to stop us from calling these properties on undefined, it's, it's not gonna work.

[00:02:32] Now, it's a common misconception that like anys are evil and you should ban them from your code base. Sometimes any is exactly the type that is most appropriate for a given situation, and a great example of this is console.log. Any value you can create in JavaScript you can pass to console that log.

[00:02:51] There's literally nothing that you can pass to it that it will fail to serialize, I believe that's true, that's a pretty sweeping statement. And you can see here like it's typed as any, there's not really a purpose to message and optional params. You all have use console.log, you just pass it a bunch of stuff, but the first argument isn't any, and then you have a rest param of type any array.

[00:03:22] So you pass it as many anys you want and it will log, this is the actual appropriate type to use, or I will say, a top type is appropriate to use here. There's another type that TypeScript provides, and it's called unknown. So, performing the same tests that we did above, we can see that we're allowed to assign a wide range of things to unknown.

[00:03:51] And this, in fact is what makes it another top type, it's ready to accept any value. But there is something different about this. We can't use an unknown until we perform a little bit of an investigation into what it is. It can accept anything and that makes it a top type, but we have to narrow this value.

[00:04:16] We have to use a type guard before we can go and use it for just about anything. And so you can see here, we're busted Typescript's helping us avoid having an improper assumption that like all of this stuff is my unknown variable. It's a number, it's 14. It doesn't treat it as a number, but it certainly is not willing to let us use it until we apply some type guards here, which is exactly what we're about to do.

[00:04:47] And I've left some comments here, going back to the analogy we started in TypeScript fundamentals V4, where we think about types as representing a set of allowed values. I've put the sets for each branch of this condition, or this conditional flow, as comments along the way. So, this code up here, my unknown, it's an unknown, that means it's still a top type, right?

[00:05:17] And that's true above this first if statement, and within the if statement. But the code block following it, you can see we've said type of my unknown is equal to string, well, now it's a string. So this is the same narrowing behavior that we see with other kinds of values.

[00:05:35] This is what you would see with a union type, where you're trying to handle one possibility and then another possibility. But this is how you use an unknown. You can almost think of it as like, you could do the same thing with any, but the main thing is that it prevents you from using the variable before you narrow it down.

[00:05:58] You can see we narrowed again, here's the number, and then here we've got an else part. And we're back to my unknown, and that's because like it could be so many other things. TypeScript has no way of representing the set of all possible values, except strings, except numbers, there's no way to represent that, at least in the publicly usable syntax.

[00:06:23] It may be possible to do it in the internals of the system, but nothing that's part of the language lets us do it.