741

March 11th, 2024 × #TypeScript#JavaScript#Web Development

TypeScript Interview Questions - STUMP’d

Wes and Scott quiz each other on advanced TypeScript features and syntax in a segment they call 'Stumped'.

or
Topic 0 00:00

Transcript

Wes Bos

potentially 4 big red x's on this side of the table. Node not I'm not gonna do, like, how do you infer a record conditionally? Because, like, that's a whole another level of of TypeScript.

Wes Bos

This is more just like user features that that we'll be talking about today, but a couple couple little nuggets. We're gonna do 4 questions each. So, hopefully, between all of the 8 things, you can learn a thing or two.

Wes Bos

Sanity? We had we had some rage clicks the other sorry. Let me don't stop the ad read yet, Scott. Let me tell you about my rage clicks the other day. We had Yes. Somebody, on the website, and I got a email. And they had a couple rage clicks and then a dead click. And Essentri does this detection of when somebody clicks on something and there's no noticeable change in the UI, like nothing happened, that's a dead click. And then if someone does that repeatedly, that's a rage click. And it shows it in the playback, and it was really interesting because you can watch. It's a 15 minute progress of somebody. So, obviously, there's something something going on there that, they were obviously trying to click something, and it wasn't working. And I was able to play it back and kinda see what was going on with the user and and figure out what actually caused this specific error. So check it out. Anyways.

Topic 1 02:35

Century detects rage clicks and dead clicks to identify frustrated users

Wes Bos

By the way, speaking of related, our landing page, centric.i forward slash syntax. That's a new landing page. Looks super good.

Wes Bos

Yeah. Check it out. Enough of that. Let's get into some questions. You wanna go first?

Wes Bos

Oh, combine string literal types.

Wes Bos

A a string literal type is a, when you use back ticks in TypeScript, and you wait. Are we talking about that? Now now you're confusing me of of what they are here.

Wes Bos

some root in some, like, suffix or something, and you wanted to combine some or yeah. I I thought you were asking about which what was the answer, which is the template string types. I believe that is the answer. So you use back ticks.

Wes Bos

And then inside of the back ticks, you can take 2 different, strings, or you can take a union of 2 different strings and combine them together, and it will then create a union of every single permutation. So if you have red, green, blue, 1, 2, 3, that's gonna kick out all 9 combinations of, like, red dash 1, red dash 2, red dash 3, blue dash 1, blue dash 2, etcetera, etcetera. So combining those together is extremely Sanity.

Wes Bos

And let me tell you a little kinda cool tip that you can do is you can also just type straight strings into those backticks as well. So if you have a let's say you have an invoice string and you wanna make sure that it starts with I n v. What you could do is you could say I n v and then just put a number, like, dollar sign curly bracket number inside of there, and it will say, alright. This is a type that starts with I n v and then has a number at the end, which is is really, really handy, when you have, like, things like IDs or invoice numbers where it's just it's a string. Right? But it's a more specific string.

Wes Bos

sometimes that happens when somebody uses a word for something that you you haven't used before or you're thinking about it in a different way, and

Wes Bos

Yeah. Things that make them seem a little bit more complex than they are. My question for you next is what is a TypeScript generic, and why would you use 1?

Wes Bos

a a database query. Right? You could you could query for users or you could you could query for shows.

Wes Bos

And you're not gonna make 2 2 functions, 1 for users, 1 for shows. You're just gonna have a generic query, and then you pass a generic, to that. You say, alright. I'm going to query for a user, and that will allow you to both have type safe input as well as returned value.

Wes Bos

You use the it's it's kind of like a alright.

Wes Bos

A conditional type is using the same I'm gonna have to say the word turn ternary ternary.

Wes Bos

Ternery.

Wes Bos

Where ternery.

Wes Bos

And you you do your condition.

Wes Bos

Usually, that is something like something extends this. So if if this generic can extend a string, so if a type of string, then question mark, you return your type. Otherwise, colon, you return the other value.

Wes Bos

like what you said. If some type extends another type, show 1. Otherwise, show the other. Yeah. And, like, when would you possibly want that? Well, sometimes you are looping over a bunch of keys in a specific type, and you want to check.

Wes Bos

Like, for example, I just talked about, invoice strings that start with I n v. What you could do there is you could check if the invoice string is overlaps with the type of I n v and then a number. And if it does, then you can do things like strip off the I n v dash if you want to, or you could in that case, you wanna do something different to that type, capitalize it, lowercase it, otherwise, return a different value.

Wes Bos

Here we go. I have a function that returns a promise of a user, but there are no types provided for that function, and you cannot generate the types.

Wes Bos

You cannot just write out the type yourself. How would you generate a TypeScript type for the return value of that function in TypeScript? Let me know if you want me to say it again.

Wes Bos

Yeah. You have a well, the the function itself is an asynchronous function, so it turns a promise, and then it returns a value, which is which is a user. But there's no there's no user type. So how without manually creating the user type yourself, how would you get a user type from that function?

Wes Bos

Well types in That that's half of it. But how do you Okay. It it is inferred, but how do you store that inferred value in a actual type that you can then Oh, okay. Use somewhere else in your application? Okay. Can't you just say type user equals infer and then the the

Wes Bos

Close.

Wes Bos

Okay. The answer is brackets.

Wes Bos

Two parts. First of all, you use type of and then the name of the function without calling it. And what that will do is type of will give you the TypeScript type for the entire function signature, so the inputs, the parameters, as well as the outputs.

Wes Bos

And then you wrap that in a return type, which then takes the whole function signature and and makes it just down to the return type.

Wes Bos

And but that's still wrapped in a promise.

Wes Bos

So then you wrap that again in a utility function called awaited, which will then give you the actual return value. So if you ever have functions that don't export types, the way that you can get access to those types of the functions are type of and then do a whole bunch of dancing with return type and a weighted or if you want the arguments to that function, you you just use, the arguments,

Wes Bos

Yeah. It it basically unwraps a promise. So if you ever have a type Yeah. Like like a function that returns a promise that of a user, and you're like, I don't care about the promise Yarn. I just care about the user. You can unwrap the promise with awaited.

Wes Bos

Really? Because of the event loop?

Wes Bos

Yeah. I'm not going back to to callbacks. Oh, yeah. I I see the blog post. We'll link it up in the show notes here. Nice. Wow. Good thing. That's really cool. I bet I bet it has to do with the fact that when you await something, it sticks it at the end of the event loop, and that is possibly an issue. I don't know. Like Yeah. Have I ever had a problem Wes, like, oh, yeah. That awaiting the promise. No. It's the 15 meg image that I'm, trying to download or the, like, blocking, synchronous code that I'm running on the main thread instead of in a service worker. Those are usually my issues. Yeah. Maybe though. Maybe performance is of paramount, and you need to

Wes Bos

Ah, good.

Wes Bos

So d.ts files are different than TypeScript files in that you cannot put JavaScript in them. You may only put TypeScript definitions inside of them.

Wes Bos

So d dot t s files are generally generated from a code base, that needs to be shipped. So if you are an author of a library on NPM, you write your code base in JSDoc or in TypeScript.

Wes Bos

Generally, what happens is you you generate those d dot ts files, and you ship them, alongside your repo or in a TypeScript, and then somebody can include those via their TS config.

Wes Bos

And then TypeScript essentially knows about these types that can be, used without having to import them directly from each of those values. So pretty Sanity. Also, really handy for declaring modules that do not have types for them. So, for example, the other day in the syntax code base, we used a markdown plug in to add IDs and links to every single show notes heading. So if you somebody's like, hey. I wanna link to part of the show notes, and there's no there's no IDs on your h three tags.

Wes Bos

So, we went in. I added a plug in, and everything worked great, except there was no, types for that thing. And I went into the GitHub repo. There's no types anywhere, so I had to go figure out what were the types for that, and and then I just threw them into there's a file in our code base that we can put types into.

Wes Bos

I threw them into a d dot ts file, and that and then it I basically said, declare module, whatever the name of the module was, and I wrote all the types for it. And, then TypeScript picked them up for that module.

Wes Bos

Sick. Yeah. Perfect.

Wes Bos

Ideally, no no d.ts files, with JSR. Well, JSR will generate them for Npm, but, ideally, we just consume the TypeScript directly, and we don't need d dot ts files. Yeah. I just got my JSR invite. I'm stoked to start using it.

Wes Bos

Name one difference between a type and an interface in TypeScript.

Wes Bos

Oh, okay. I got it. This one is intentionally a little bit like, because almost never matters.

Wes Bos

Yeah.

Wes Bos

Yeah. So with types and interfaces, both of them can be extended.

Wes Bos

But the way that you extend them with types is with the ampersand, and the way you extend in interfaces with the extends keyword.

Wes Bos

Do you have anything that can only be done with a type or an interface?

Wes Bos

that's what I keep saying in my courses JS it probably doesn't matter unless you're gonna hit something where, oh, I can't do it this way, and then it'll switch to the other. So there's a handful of of different ones.

Wes Bos

Interface merging is probably the most

Wes Bos

So with interfaces, you can declare an interface multiple times, and they will fold into each other. Meaning that you can declare interface window and put something on the window, and that's not gonna overwrite all of the other window methods on there.

Wes Bos

This is really handy with like, I'm using some Cloudflare stuff right now to run Next. Js, and they have their environmental variables, and then they have some some Cloudflare type.

Wes Bos

And if you wanna add on your own environmental variables on top, you don't wanna over overwrite theirs. You just wanna add yours into that. Right? So using an interface ESLint that case is the only way to sort of fold those in, because if you were to write a type, it would simply overwrite the the existing type. So that's probably the most common one.

Wes Bos

And then the other the only one of the big ones for types is that a type alias can only be done with a type. So if you say, like, type whatever equals, in a lot of cases, you can't do those with with interfaces.

Wes Bos

Same with, like, your your merging example. Right? You can't do the you can't merge strings together within interface.

Wes Bos

Yes.

Wes Bos

The triple slash directive is something that is hardly ever used. In fact, I Node the conscious decision to not include this in my course.

Wes Bos

It's for referencing external type files inside of a TypeScript file or a JavaScript file where you cannot import those types.

Wes Bos

So you will only ever see these in it's like a a thing from, like, 8 years ago. And in most cases, it's a thing from before Wes, before we had ECMAScript modules in TypeScript. So it was a way to reference where the d dot ts files lived without having to import them into your TypeScript file, because sometimes people aren't aren't using TypeScript files. You'll all you'll often see them in, like, compiled, like, iffy code that is output by a bundler, but

Wes Bos

Yeah.

Wes Bos

Alright. Last question we have here.

Wes Bos

What is a TypeScript record, and what is it used for?

Wes Bos

Sorry.

Wes Bos

Sorry. I was not confusing you.

Wes Bos

A a TypeScript record is a utility method, you Node that, for defining an object type Yep. Where the you know the type of the keys and of the values. So, very commonly, you will have a union of keys. So, like, I want the key to be small, medium, large, and then the the values will be a T shirt or a hoodie. Right? So you'll say, I want a record of the keys are small, medium, large, and the the the values are going to be type of T shirt or a type of hoodie.

Wes Bos

And then that is just a shorthand for rather than creating an object and using the square bracket keys Wes you say key in whatever, you loop over them and and and generate it for you. It's just a a handy dandy utility type.

Wes Bos

No reason why. That's just how I've done it. Just just Warp first it. You understand? Yeah. Yeah. It's like I said, it's it's just a utility method that that lives on on top of the actual TypeScript. So you can type it out yourself as well, if you wanted to. And in some cases, you you do need to type it out because if you our record does not allow you to mark keys as, optional.

Wes Bos

So if you if you want them to be optional, you either have to type it out yourself or you wrap it in like a, another utility function.

Wes Bos

Or if you wanna do if you wanna add additional properties to a record after you've looped over everything, then you would need to do that yourself.

Wes Bos

Beautiful.

Wes Bos

Yeah. Jeez.

Wes Bos

Yeah. Some some tricky, tricky things in there. So, hopefully, you learn a thing or two. This is Scott and I put ourselves out there, to be embarrassed about these things so that you will the listener will learn a thing or two.

Wes Bos

I don't know what any of this stuff is. Hey. That's how it goes. Right? You gotta learn it. Yeah. And even just, like, having this stuff rolling around your noggin so that Wes do hit these problems, you'll say, ah, those guys talked about that. What was that? You know? You can look it up and figure out how it works.

Wes Bos

Alright. That's it. Thanks, everybody, for tuning in. We will catch you later.

Wes Bos

Peace.

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window