348

April 28th, 2021 × #TypeScript#Fundamentals#Generics

TypeScript Fundamentals — Getting a Bit Deeper

Getting deeper into TypeScript fundamentals like any vs unknown, generics, inference, definitions, and assertions.

or
Topic 0 00:00

Transcript

Announcer

You're listening to Syntax, the podcast with the tastiest web development treats out there. Strap yourself in and get ready. Here is John Talinski and Wes Bos. Welcome to Syntax. This is a podcast with the tastiest web development treats out there. Today,

Topic 1 00:16

Continuing fundamentals of TypeScript

Wes Bos

We are continuing on our fundamentals episode on TypeScript.

Wes Bos

And this the first one we we did, the very high level, the very rid Basics and whatnot. And in this one, we're gonna attempt to get a little bit deeper, a little bit more into the nitty gritty of of things like that as well as re Follow-up on a couple things from a few past shows.

Wes Bos

Today, we are sponsored by 3 awesome companies. DQ, they are the pros in accessibility rid Testing a lot of Rocket, which does your client side session replay and Mux, which is APIs For video on your website, I'll talk about them all the way partway through the episode.

Sponsored by accessibility testing, client-side session replay and video APIs

Wes Bos

With me today is Scott Talensky. How are you doing today, Scott? Hey.

Scott Tolinski

Doing good. Wrapped up my course last week that I'm recording on node authentication part 2. Rid So, that is prepped and ready to go by the time you're listening to. That'd probably be out for a month already, and many people will have completed it. So read. I am ready to get that out of my, off of my plate here and ready to start diving into some interesting code skills, some interesting stuff that we're working on for the site. So it's always a good feeling when you get something that's been, you know, a project that you're working on every month to get get it out the door and and get working on some stuff. It it feels rid. Like, maybe I should take a day off. So I'm like, oh, maybe I should just take a day.

Wes Bos

I I have those days every now and then where it's just like, like, ready. Done. I'm done that big thing. Mhmm. Now I'm about to start on my next big thing, but sometimes I'll take a day off in between and not necessarily, like, just, like, Loaf around, but just, like, work on, poke around at things, check out stuff I've been meaning to check out for a while, write notes, rid. The emails, those are, like, in between days are really nice to have, especially because there's, like, all the weight of the last project is off your

Scott Tolinski

Off your shoulders. Yeah. There's so much of that that I I, well, it was funny because it was, like, Friday, I finished Friday, I finished the the, like, the actual re recording, and I was like, you know what? I'm gonna take the rest of the day off. It was only, like, 3 o'clock. So it was, like, what? Like, I took 2 hours off or something. But yeah. And then Courtney's like, oh, you finished? I was, like, rid Yeah. Well, I still gotta record the intros. I still gotta rerecord video number 5, and I still have to rerecord the ending of number 1, but it's done. Whatever.

Scott Tolinski

It's not it's not really, but I'm kinda convincing myself it is. Okay.

Topic 3 02:33

Difference between any and unknown types in TS

Scott Tolinski

TypeScript.

Scott Tolinski

Let's get into TypeScript here. We did a really long TypeScript episode. We're gonna be doing a bunch more. We're gonna be doing an episode on TypeScript in React. So if you if you notice some things Maybe that we're not talking about here. We're gonna be talking a lot about TypeScript, especially this year. I think TypeScript's already kind of reached that inflection point where where So many people are using. In fact, my latest 2 node courses didn't use TypeScript, and I'm just using straight up node. And I felt, like, people describe that feeling of of Feeling naked without it having missing those features, and I couldn't tell you how many times I was like, what are the parameters for this? Let's go look it up or, You know, even, like, very simple bugs that found its way into the code, it would be omitted through TypeScript. So I I mean, I think we're seeing TypeScript really become rid The thing that people are are landing on this year. So let's get into some deep end stuff with TypeScript.

Wes Bos

Yeah. I I'm not sure if we we covered this or not, but I rid. Whipped up a little tweet tip for this the other day, and I thought we'd mentioned on the show as well, is the the difference between any and unknown.

Topic 4 03:40

Using never type in React for mutually exclusive props

Wes Bos

Rid. So we talked about any, I'm pretty sure. And any is if you are unsure of what type rid is going to be coming into a function or anything like that. You can just slap in any on that. And what that will do is it will say it can be literally any type. Rid And it's generally seen as sort of a a cop out because you are giving up a lot of type rid Safety and security and and all that stuff with any because you're basically saying, I'm not sure. I'm not sure. Whatever. Anybody can come in. It might be a string. It might be a number. Re Might be an array.

Wes Bos

And, usually, people do that when they're converting existing code bases where they explicitly type it as any. Re Then we also have unknown, which is very much the same thing as any, except that before you go ahead and use rid. The value that is any or unknown, you have to explicitly check the type. If you are writing a function rid. And an argument's coming in, and you say it's unknown. I'm not sure what type of argument would this would be. And then you go ahead and try to put that rid. Argument into, like, a string. Like, you try to console log and interpolate it. As in any value, TypeScript's gonna be like, alright. Go ahead. Sure. You can do you can you can rid Add to that thing. You can put it in a string. You could recall it like it was a function. Whereas an unknown value, rid You can't do anything with it unless you explicitly

Scott Tolinski

check the value of it. So you'd have to say, if type of

Wes Bos

rid. Unknown value is equal to a string, then go ahead and concatenate onto it. Or if type of unknown value is a function, then you can go ahead and call it. So rid. At least maybe we'll we'll save this for the end, but, yeah, let's save for the end.

Wes Bos

Which one would we Scott and I use? I'm gonna we have a thing at the end of the show here, which is, like, personally, what do we use? And we'll we'll say which one is is better in those cases. Ideally, neither, but if you have to, Which one? Yeah. It's funny because, like, I think that is one of the biggest barriers to entry with TypeScript is that there are a lot of

Scott Tolinski

Things you like intersections in the road where you have to make a decision, and when you're first learning, you might not even understand the decision that you're making. Like, types re Do I use a type, or do I use an interface here? They're both usable. So why would I pick 1 over the other one, and then you have to go down that rabbit hole before making a decision when ultimately, You're probably just better off just picking 1, going with it, and then finding out later what the, you know, what the best course of action for you is. So there is so many of these, like, do I do this or that? And I think we'll we'll be talking a little bit about the decisions that we make in those forks in the road.

Scott Tolinski

We also talked a little bit about never being a type, as in rid The type that would say that there cannot be a value assigned to this.

Topic 5 06:30

Using never for enforcing only a or b props

Scott Tolinski

Somebody had posted us a really nice little code example.

Scott Tolinski

It was Cartato

Wes Bos

Telefonica? Yeah. Brazilian name. That's a very

Scott Tolinski

Fun name to say. Yeah. Yeah. And so his example says, you can use the never type in TypeScript to make React components accept an attribute Only if one isn't being used.

Scott Tolinski

So in this example, he gives the example he says can have a headline or rid be gridless.

Scott Tolinski

So he has 2 different props. 1 is headline that has sub properties of it, which is, like, number, text, whatever, And then another property, which is gridless. And so he'll have 2 different types here, one of which has headline being a thing, but gridless Having the property of never and the other one of having headline being the property of never with gridless being a a thing. So, therefore, 4, you could have the component defined as in this situation, if you define it as having a headline, it cannot have a grid list or else it it will throw an error saying, Hey. TypeScript should not have a property here. And, likewise, if you have a property for, in their example, grid list, then headline Would also fire if you had something in there. So it's a really neat situation where you could have, like, alright.

Scott Tolinski

This component will have rid. 2 completely different use cases if 1 property exists or perhaps, the outline or whatever is going to change in it. So, rid. That that was a really neat neat, way of looking at this because on its surface, you might think, why would I ever need to say something doesn't need to exist? Why would it just not exist? Rid And this is this is the main reason. If you wanna have situations where one thing exists explicitly where something doesn't exist in rid Vice versa or whatever. You could do that with the never prop or the never type. Yeah. Because you don't wanna get into the situation where you're passing data

Wes Bos

rid. That looks like like partial data where you shouldn't be.

Wes Bos

Some really good comments there. There's another really good example in the comments where it's just basically ready. A and b, and you must pass either a or b, not both. Yep. You can use never for that, but you can also use what's called a discriminating union.

Wes Bos

Rid. And a union in TypeScript is where you pass multiple options. You could say someone could pass me a number or a string or a rid. A dog or a sandwich.

Wes Bos

Like, those 2 different types. And a discriminating union is where some of the properties overlap, And it will make sure that you're not passing some sort of, like, mishmash between the 2.

Topic 6 09:03

Definition files explain untyped code to TS compiler

Wes Bos

So if you're passing Something that barks, you're not also passing toppings.

Wes Bos

I don't know if that's a good example, but yeah. Well, yeah. I mean, a works. Yeah. Alright. Let's talk about dotd.ts files. These are something that you will probably see in rid Projects that you download or you get clone or or whatever.

Wes Bos

And you might be saying, what what is that? What what are all these these files? And rid A dot d.ts files are what we call definition files in TypeScript, and they are usually written rid For libraries that were not written in TypeScript, but they need to have definitions in order to work in TypeScript or have the rid. Really nice auto completion. So we've talked about this on the last episode, but if you have a library that was not written in TypeScript, Almost always, there'll be somebody who has already written the types for it, and that person will basically write all the types for a module, rid But only what they take in, what they return, what types they are, and any any any custom types rid Type aliases and interfaces for that library. So if you see a d dot ts file, that is just a pure definition.

Wes Bos

You, yourself, rid. You don't have to write those if you're writing pure TypeScript because you generally, you write the definitions and and whatnot as part of writing TypeScript.

Topic 7 10:21

Definition files not needed for pure TS

Wes Bos

But, again, if it's, you've got a project from 3 years ago and the the thing wasn't written in TypeScript, Then you can easily write a d d dot t s. We you can also write comments. We'll talk about that in just a bit with JSDoc or TSdoc.

Scott Tolinski

Rid d.ts can be helpful for globals too, though. For instance, like, if you need to define or extend the type of window, we have a rid globals.d.ts where we declare global have an interface of window where we can extend anything on window. Let's say maybe you have a a library that Is it being imported from npm and is just available to us on the global? Yeah. Snipcart's like that. Snipcart, if you wanna access snipcart, it's window.snipkart because it's it's just a global like, a good old jQuery plug in that is just thrown on the window in order for anyone to be able to access it. Yeah. So is our our video player. So, like, the in those kind of situations, you do need to potentially augment window. Otherwise, that can be one of those, like, That can be one of those time syncs where you're just so annoyed with TypeScript where, you know, window is not property is not defined on window, and you're just like, great. Well, what do I do What do I do now? Can you use a window to any or something? You know, obviously, you don't, but it can be one of those things that is extremely frustrating to have to deal with. Okay. So, d dot t s, I had a little interesting issue with d dot t s that I maybe should call out here too. Yeah. Fast If I had a library. Right? So Fastify is our our API server, and it's a node server, just a normal HTTP server like what you did Expressware, and there's extensions onto it like plug ins.

Scott Tolinski

So what was really interesting is we had a Fastify cookie plug in that we registered, and rid Typically, what we're doing in other files when we want to access, like, the request and response of a query, you could just access those as response dot Whatever. Or in in FastAPI's case, it's reply dot whatever. Right? However, cookie only becomes a property on reply because It's using that extension. And so that was kind of an interesting TypeScript issue because what would happen would be in another file when we were to look at the reply type.

Topic 8 12:05

Global types may need definitions too

Scott Tolinski

The reply type would be coming in from Fastify proper and not from Fastify cookie, and we actually had to import Fastify rid. Cookie on that page, even though we weren't using it, just so it would load the d.ts file so that it would get the correct type on the response there. So I thought that was a little bit of an interesting thing where, like, if if you have some extended .t.ts that sometimes you might need to import the package to get it to ready to pick it up. Yeah. Like, sticking stuff on your request or your response is

Wes Bos

pretty common practice in node land because you rid. Have these middlewares where you need to hot potato the data down the thing. So being able to modify what those requests and response look like rid is key. Yeah. Totally. Let's talk about type generation. We did a really good show on this where Scott basically talked about how All of his, not only TypeScript, but also, like, the React Hooks and everything is generated, and it's a pretty Common thing to be able to generate types from your JavaScript or from your output or from your schema or for whatever. Because A lot of times your data is being modeled in something that is not TypeScript.

Wes Bos

It might be a MongoDB schema. It might be a MySQL schema, might be GraphQL.

Topic 9 13:56

Type generation from DB schemas or GraphQL

Wes Bos

It might just be, what's the other one that people are using? I was using it the other day. Swagger is another one where you can describe your API in the schema rid File. I've used 1 in the past where you just take your JSON output and can immediately convert that into re types. That's really handy if you have, like, an API you're working with. There's no types available. You can just take a dump of all the data that comes back from that JSON API, rid Feed it through one of these things, and it will give you TypeScript types out the other end. Yeah. Totally. And, I'm sorry for laughing at you saying You could just take a dump.

Scott Tolinski

You could just take a dump. Yeah. That's really mature of me. So, the Cool thing for me about type generation is that, like, if we're generating a type for the user that's coming back from, let's say, in the UI Or or API. Right? The the type for the user or the tutorial or whatever is generated as in this is the actual rid thing that is going to be coming back from the GraphQL query, and, therefore, we don't have to type that in any component ever. We can always just import it from 1 single source of truth, And therefore, we know that, you know, that single source of truth is going to be accurate in terms of what the API is going to receive.

Scott Tolinski

So if a field's potentially null, it's gonna be potentially null from the point in which the data comes in all the way to the the furthest out point in which that data is used, And we can accommodate accordingly, or, you know, if something doesn't need to be not null, then we can adjust that in our API sense. But either way, It really allows us to have this single source of truth for all of our API on the front end UI client, whatever, and everything just sort of talks to each other. So in my experience, Having types generated like this where possible has been just a fantastic improvement in the way that we write TypeScript because before that, I was doing it all by hand. And, you know, you run into situations where, like, well, hey. This shouldn't be non null, but the query says it's non null, so where do I for that, and and being able to to really have full control over a single source of truth is really pretty amazing.

Wes Bos

What else is pretty amazing?

Scott Tolinski

Yeah. Woah. Oh, I was saying the same.

Sponsor: LogRocket session replay debugger

Scott Tolinski

Yeah. Same ad transition. Tell me, Scott.

Scott Tolinski

Well, that was pretty amazing, but it was also pretty amazing is LogRocket, one of our sponsors today. Now LogRocket is the perfect place for you to see rid All of the areas that happen on your site in a scrubbable video replay.

Scott Tolinski

This is the type of thing that debuggers Just go nuts over because debugging is hard when you can't see what happened. Right? We're often I I like to say that we're investigators trying to solve a crime without, You know, having well, we have access to the crime scene. Right? There are only so much you can do to solve the crime if you have access to the crime scene, but if you have a video of the crime being committed, then Shoot. Well, that makes it a lot easier. So with Lock Rocket, you have the video of whatever crime your users are committing against your code.

Scott Tolinski

And by that, I mean, you can see with the scrubbable video replay, network request, error log, console log, Redux store, any of that stuff and more.

Scott Tolinski

Rid And this just makes solving bugs way, way, way super easy. So head on over to logrocket.comforward/syntax sign up

Wes Bos

today and get 14 days for free. Thank you for LogRocket for being a sponsor. Let's talk about generics first. Sometimes you'll have a Let's use a function as an example. A function that is called make food. This is my example. And that function can return multiple types. A good return.

Topic 11 17:33

Generics allow varied return types from single function

Wes Bos

We don't just have a generic food type. We have a specific sandwich type, and we have a specific pizza type. Right? Rid. And sometimes you'll find yourself duplicating functions where the internal code to create those rid things, whether you're hitting an API or validating data or whatnot or grabbing data from a form input, you were like, oh, this this code looks very much the Same, except that they are returning totally different types at the end of the day. So when that happens, rid You can get into what is called TypeScript generics, and they're kind of like functions for creating types where the output of that rid. Type is varied based on what you pass in, and I'm using air quotes here to pass in because you use the you've probably seen this before. It's with the rid. Angle brackets, and then they usually use the variable t.

Scott Tolinski

Not sure why they use t, but it when I first got into it, I was like, no. Can I just say that is my biggest gripe with, 1, people writing TypeScript, but, 2, people trying to learn TypeScript? That Sort of t bracket whatever inside of there when they say, oh, t is equal to whatever your thing may be. Like, that is not helpful. That is just rid Straight up not helpful. And in my opinion, makes learning generics just about impossible unless you come from a background where you have used generics in rid. For me, it took writing Rust code to really get generics because the types are so, like, baked in. And so, like, for me, it was like, I don't understand why I would use generics here or when I would use generics, but the moment I see an example, like, what we'll talk about with promises is when it finally clicked for me to say, like, Oh, I get it. But at the same time, like, man, the t or just some obscure letter or whatever to define the the generic type. Like, that's not helpful. I don't get it. I don't get why people would do that. I thought that it had to be called re Me too. I because everybody just use t. Like, what's up with t? Why is everybody using t? And then if you if a multiple, you can have multiple just

Topic 12 18:27

Promise is good example of nested generic

Wes Bos

rid Just like you can have multiple arguments in a function, you can have multiple generics in a type. So they they start using h and s, and and then sometimes you see, like, rid. It takes t and then t extend or h extends t. And you're like, what is going on here? And so let's just be very clear. You can use whatever words you want. Yeah. As a generics, like the word pizza instead of tea. Or sorry. No. No. It wouldn't be pizza. It would be, like, Food or type of food or something like that. I mean, it could be pizza because there's types of pizza. There there you go. That's true. It could return.

Wes Bos

Rid. That's really handy again because the type that is returned will be a variable type.

Wes Bos

Some other examples here is re Query selector can use generics.

Wes Bos

So if you select something like, you use query selector and you select an element rid That has a class of media on it. But right now, TypeScript doesn't know if unless you straight up select it with a rid Query selector video or query selector IMG.

Wes Bos

If you pop a class on it or you don't have the you don't have, like, video dot media, rid. TypeScript will just fall back and say this thing is an HTML element, which is the very lowest level element you can get. And you don't have access to all of the rid. Properties on that element that are specific to the type of element. So for an image, you wouldn't have access to the SRC attribute.

Wes Bos

Rid. For an in for a video, you wouldn't have access to play, pause, is playing, all of those properties and methods on it. So what you can do with query selector is before you open up the parentheses to select the thing that you want, use angle brackets, and rid. You pass it the type that you expect it to return, like HTML video element or React functional component or whatever the rid is that is needs to be returned, but you wouldn't use React with Curves selector. That's a bad example. And then that gives you full rid access to all of the actual properties

Scott Tolinski

and methods that you would would expect. Yep. Man, I'm so glad that we we are on the same page with that tea thing because It it makes so much more sense when you think about it as being, like, in the way that you just described it. One of the the with the first places you might even see this is when you're trying to type a promise Because okay. So a function, let's say it returns just a value, a string value, but this function is maybe an asynchronous function, or maybe the function Being ace an async function returns a promise. Right? And so maybe you've just coded a function that returns the promise. At the end of the day, The type that you care most about is what comes at the end of that promise. It's the string. Right? It's not necessarily that it returns a promise. Granted, you want to know this thing returns a promise, but The thing that you the data value that you're usually trying to get at maybe perhaps when you're awaiting or on the then is going to be the return value or the eventual return value. And so, typically, the way you'll see these promises typed is via the promise keyword, which is just built in. You don't have to do anything. It's capital p promise rid Brackets, and then you have the return value, which means that this is basically giving you 2 benefits. 1, it's letting you know what the eventual return type is rid to be, but it's also going to make TypeScript aware that this thing needs to await on the results of a new promise.

Topic 13 22:51

Reading complex generated types teaches generics

Scott Tolinski

So this can be really helpful, especially in a sync await code where, rid you missed that away keyword or perhaps you added an away keyword to something that doesn't need it? TypeScript's gonna know. It's gonna let you know. JavaScript, you add an await keyword to something that doesn't need it, or even worse, you forget the await keyword, it returns a promise, then you check to see if the thing is there, and, well, it returns a promise. The promise is there, so that's gonna return true no matter what. I've had that bug before. I don't know if you had do you know what I mean, Wes? Where your something returns a promise, you forgot to await it. Yeah. And you're left with the promised value, which is truthy. So if you're checking if it's true or false y, then, you know, that right there is worth the price of entry for TypeScript to me because, hey, you're always gonna know what is a promise and what's not a promise. That's a perfect example of a bug that you'll catch in your editor versus having to go to the browser, refresh, run the thing, and check it out. And, like, rid It saves you 20, 30 seconds from hitting that bug because you don't even hit the save key, and you've got these underlines and whatnot showing you. Hey. Hey.

Wes Bos

This thing is returning a promise. I expected it to return a promise, and you're telling me it's returning a string or an order or something like that? Yeah. Totally. I even got into it a little bit further where when I was working on selling my T shirts, I built a generic re Request function that would hit the API, and it would JSON stringify the body. It would apply the method to it. It would add headers with API keys. You know, like, If you're not using Axios and you just wanna use fetch, there's always, like you always make, like, a tiny little function that sorta tucks away all the complexity of fetch into a nice little Function. Right? So I called that request. Right? Yeah. I don't do that. I I just write fetch every time and write the options or write, like, the options in an object and then spread them in there. I've never write a wrapper around fetch. I don't maybe it's just because I never use Axios. So to me, it's like that's the the normal way that I've done it. Yeah. It's just rid Par for the course? Yeah. Yeah. In my case, it was like, oh, I have to, like I don't wanna import the API key headers into every single one and rid. JSON stringify the body every single time. I just wanna be able to pass it an object.

Topic 14 24:59

Generic types can be inferred from arguments

Wes Bos

In my case, it was probably because the API was a little obtuse, so I needed to simplify it.

Wes Bos

So what I did is I made a request object or sorry. I made a request function, but that request function could return rid. An order type could return a customer type, could return a product type. You you get the point. Right? Like, that request could return lots of things. So in my case, I had re A function that returned a promise, which had a request, which in that request returned in order a customer or product. So you can nest these things rid as deep as you want. And it's not uncommon to have promise, angle brackets, request, angle brackets, order Or or customer or product in that case. So that was something I ran into. I was like, I've never done more than 2 before. Like, how do you do that? And I just I just tried it, and you can do it as as many as you want. Looks a little funky.

Sponsor: Deque for accessibility testing

Scott Tolinski

Some of my my biggest cutting my teeth with generics has been in reading the types that my our cogeneration produces.

Scott Tolinski

Like, if you wanna see nested generics rid. And and and types written in a very, like, holy cow way. Those kind of generated ones, it's not like they're bad because there's a lot there. Right? It has to rid. Override a, or it has to, like, augment Apollo return. It has to have working examples for non nullable Fields. There's a whole bunch of stuff that goes in there. And when you examine some of those, like, really crazy types, you start to get an eye for a little bit of, like, what that looks like. Because let me tell you, I'd as somebody who, you know, hasn't done a ton ton of type languages outside of TypeScript, rid The usage of generics was one of the things that really confused me when I I first started getting into it. So Yeah. The the generics are pretty

Wes Bos

They're not hard, but like you said, like, it's not something I've run into myself before either. And it's just something that happened when I was learning JavaScript rid. 10 years ago, it was, like, the 1st, like, big language I was actually learning, so I was running into to lots of things like that. One other thing I ran into rid was inferred generic types where I made a function called make a bunch of, and then that took in a food Object and how many you wanna make for that specific type of food. So make a bunch of has a generic of f, Which is food. I probably shouldn't call it f as after we just went through that whole thing of tea not being good.

Wes Bos

And The type of the generic was inferred based on the type the first argument that was passed to that function. That's rid Something I had not run into myself as well. So sometimes functions can infer the generic type rid Just by the arguments that are passed to it. Maybe I'll put a little example of of how this works in the show notes rid Because, it's not something you run into every single day, but sometimes you'll see people using a function that has a generic but not actually passing the type with the angle brackets. And that's because the value can be inferred instead of being explicitly passed. Wild stuff. Wild, wild stuff. Hey. You know what else is kind of hard but not rid. Too hard when you have the right tools in your corner? Accessibility, testing, services, and whatnot. We have a sponsor called deque, d e re hue.com, the makers of the axe dev tools and trusted leaders in web accessibility.

Wes Bos

Rid. They have a really wicked dev tools you can install in your browser, and what it does is it automates checking of any accessibility issues that are on your website. So You've got a website. Right? That's why you're listening to this podcast.

Wes Bos

You might have accessibility issues. You probably do have accessibility issues on your website. And Even if you've tried your hardest, there's probably a couple little things that here and there that you have. And I want you to go ahead and use the axe dev tools. So you run it on your website, And it will give you a whole list of everything that's wrong with it, why it's wrong with it, and, generally, they'll also tell you how to fix it. They rid Pretty much do everything but just go ahead and fix it for you, which is really cool. So you wanna check it out and run it on your website and go to d read. Qdeque.comforward/syntax, and you're gonna if you want, they have a very, very generous free version, but they also have a rid Pro version, which has automated testing, guided testing. You can test just part of a page if you want. You can rid. All of the results if you want machine learning enhancements, some pretty cool stuff on their pro plan. You can get a free 14 day trial rid Or use a coupon code syntax for 20% off. Again, dqdeque.comforward/ syntax. Thanks so much to DQ Systems and the axe

Scott Tolinski

rid DevTools for sponsoring. Great. Alright. So next section is going to be a type assertion, which is funny. When, Wes had this in here, I had to do a double take. I've always just called this casting.

Scott Tolinski

But, Wes, you had a interesting little tidbit about why it's considered to be,

Topic 16 29:56

Type assertions vs type casting in TS

Wes Bos

assertion and not casting rid Yeah. Inside of TypeScript. These are the kinds of things I hate about programming is that if you say the wrong one, somebody will come along and correct you. It's actually, it's not a rid Actually, it's not, asynchronous. It's it's parallel or or, no. No. Not that. What's the one that everyone always gets is rid JavaScript is concurrent Oh, yeah. Not I don't know what it is. Who cares? We we understand how it works. Right? So, apparently, the difference is type assertion rid is just that author time, whereas typecasting infers that it will have runtime support, which means that, like, in the browser, you would have rid Support for that. And you don't because TypeScript is a compile time language. It's there's no support for TypeScript in the browser yet.

Wes Bos

We might get types in JavaScript, and then we'll say goodbye to TypeScript.

Wes Bos

But right now, it's not. The proper word for it rid is assertion, but from what I'm seeing is most people call it typecasting.

Scott Tolinski

Yeah. Well, yeah, that so if you accidentally hear me say casting and you disagree with that, well, That is just because it's been programmed into my brain. Think about as being casting for the past f amount of times. So or t. For the amount of t amount of times, that's how how long I've been thinking of this as being casting. T. That's a good yeah. Yeah. So, basically, it's an override. It's to say that This thing that you either cannot infer or you are inferring as something potentially wrong, It allows you to basically override that and say, like, hey, TypeScript. I think I know a little bit more about those variables of value than you do. I've had to do this sometimes in React components where it, like, just won't be satisfied if the thing is actually there or not even though I've done rid A conditional check to make sure that the thing is there. I've had to say as blank just so that it gets rid of that error that it's giving me. So A lot of the times when I'm using assertion, the syntax is some value as type, and that basically reassigns the type of that value to be rid The thing that you're saying it is as.

Topic 17 32:06

Assertions allow overriding TS inferences

Scott Tolinski

So if I have a sandwich and that sandwich is actually a pizza, I can say sandwich as pizza, and then TypeScript's gonna get off my case about talking about pepperoni on it. It's sort of, an escape hatch in TypeScript because,

Wes Bos

Ideally, you wouldn't have to use type assertion because everything you've written is perfect, and it just it knows the types and and whatnot. Or rid. Or even if you you type it yourself, it knows it. But sometimes, TypeScript will say, like, alright. I was not expecting this thing to come in. Or rid. Sometimes they'll just give you a lower level like a HTML element. And you're like, no. I want all the typings for a video element. So you could you could assert it as rid HTML video element, and that that gives you again, it gives you all the properties and methods that you have. So it is sort of like any. Yeah. I

Topic 18 32:58

Assertions are escape hatches like any

Scott Tolinski

rid I was gonna say it's like anywhere if you want to maintain type safety down the line. It's like anywhere. It is. It's an escape hatch. It's the ability to say like, hey, TypeScript just let this one go here. Yeah. But then later on, if you're accessing properties of that thing, you still want to be able to get that type completion. You don't wanna just be like a free for all. Rid. That's the reality, especially if you have a code base that's been a lot around for more than 3 weeks, something like that. You know? Yeah. That's the reality of of web development is sometimes this stuff isn't absolutely perfect, and you could either do

Wes Bos

6 hours of refactoring your core library rid Or just pop a little assertion on there and and move along with your day because at the end of the day, some of us have to ship stuffing and do our jobs.

Scott Tolinski

At the end of the day, some of us just wanna tell TypeScript to f off for a second and let us do our job.

Wes Bos

There there also is another way to assert rid where you put angle brackets in front of the value. Yeah. And I personally have never used it. Oh, we're supposed to wait for the end. Oh. This is another way. It's it's It's not as popular because of React world because it it looks like it's JSX even though it's not. Yeah. That is kinda confusing, and I think The TypeScript sort of React interface can get a little bit

Scott Tolinski

little bit cluttered there with the way that looks. Now this next section is gonna be on TypeScript with rid Out TypeScript using a JS doc and TS doc. Now I have not done any of this, but I know there's a huge proponent of or a huge group of people who are All about either doing this as the primary means of writing TypeScript or have been doing this alongside of their their TypeScript, which is read. To write your types in at JS doc comments. Now if you've never used JS doc comments, you may have seen them in source code before.

Scott Tolinski

They're comments that are very structured to look specific way, to document a specific function method, whatever, And that comment can be used for all sorts of stuff. I mean, there's documentation generators based off of GSDoc. GSDoc is is the king here because It's been used for so long that there are a lot of really neat tooling around that from developing your documentation for this thing, and Versus Code has really good support for it as well. Now the coolest thing about it with TypeScript is that you can type your code via these comments so that instead of writing your JS doc And writing your TypeScript, you just write the JS doc, and you get the types out of it as well. I haven't used this at all, but I think it's a really neat thing because you get that kind of re Built in documentation aspect of things. Yeah. I

Wes Bos

really, really like this because maybe we'll do an entire show on on how this works or a little hasty on it. Rid. But at the end of the day is if you have a JavaScript website like, my personal Gatsby website is just just JavaScript.

Wes Bos

Rid. I was working on the other day, and I was like, oh, man. I miss all these nice auto completions in here. You can just go ahead and write comments rid Above all of your variables and and all of your functions as to what what the arguments are. It even has one thing which I find nicer than TypeScript is you can add comments to the functions as well as the returned values. So when you hover over top of it, it will give you a little bit of a explanation as to what it is that it's returning.

Wes Bos

And I think this is really cool. We had Brian LaRue on, rid. And he loves TypeScript.

Wes Bos

He said he writes all of it in JS doc format. There also is TypeScript is working on TS doc, which re Should give us the same thing at the end of the day. So I think we'll probably wait a little bit until some of the stuff is updated, but they're also I can't find the tweet right now. Somebody on Twitter sent me a read. Blog post that they wrote.

Wes Bos

They don't think that there's any features that they are missing, and they just write regular JavaScript and just all rid JSDoc above all their functions.

Scott Tolinski

That's wild. That's that's wild to me. That could be a nice barrier to entry minimizer where you still get some of these These things and especially if you already know JSDoc.

Wes Bos

JSDoc is a whole thing in itself. You know? I mean, it's a whole syntax and language, essentially. If your Whoever's on your team doesn't want you doesn't wanna switch to TypeScript because of whatever reasons Well, it's a big buy in. Yeah. You can just start writing it yourself

Scott Tolinski

in comments above all your things, which is really cool. Even just changing the file extensions, that was a pain in the butt. Yeah. Change the vital extensions as you have. I'm sure you write a script to do it. But But when you change a file extension, all your code's gonna break, so you might as well spend the time to massage each component as you do it if you're converting a project. Way, you don't even have to convert a project. You can just start getting some of the benefits for it. I, I thought I'd give this a go. Maybe even just even inside of a a TypeScript thing because sometimes we, like, talk about stuff on the show that seems really appealing, like, when we're talking about it specifically, like, who is that 1? Conventional commits. Rid. And then I installed a conventional commits helper on my on my computer. So now whenever I do git commit, it just Automatically fires up conventional commits. I don't even have to think about it, and all my commits are better. Oh, man. So maybe I should try giving this a run here just to see how it goes. You know what? One of the things that I gave a try to to see how it went, and it went really well, was using Mux. And I'm talking about mux dot the perfect video solution for web developers who want to build video content. Now I I I know a little bit something about building video content. If you've rid followed me at all or listen to this podcast, you might know that I created LevelUp Tutorials, which is a video streaming service for web development tutorial content.

Scott Tolinski

And when we were picking our video providers, there was a ton of decisions we had to make from where to ingest the The videos where to host the files, what type of code we had to write to interact with the APIs. Not only that, but rid The really in the weed stuff about all of the versions of the all of the video files you have to create is absolutely a nightmare, and rid. Mux really takes that nightmare and turns it into a beautiful dream. And I I say this as a very, very bought in user of Mux. I absolutely love this service.

Scott Tolinski

So Mux is the perfect place for a developer to host their video because it gives you a perfect API. And if you've ever used anything like Cloudinary, this will definitely make a ton of sense to you because the types of videos that are encoded and served are only what people are actually asking for, meaning that you don't have to host and serve A whole bunch of 800 different versions of each video keeping your costs down. And not only that, but the transcoding is insanely fast so your users don't even notice. So the next time you hit a video, that video is already waiting for the next person. It's crazy good. You also get thumbnails, animated GIF previews.

Scott Tolinski

Rid It's so funny. They have a little liner in here that says that little that little thumbnail scrubber thingy, consider all of that solved. They're just a single get request away from your video stream. So Mux makes so many things working with video easy. It is the API first video platform that if you're a developer, rid You're going to love. So check out mux.comforward/ syntax. That's mux.comforward/ rid syntax and try the, amazing developer API first video platform today. So thank you to Mux for sponsoring.

Wes Bos

Alright. Let's talk about the big question that everybody always has is, what's the difference between types and interfaces in in TypeScript? Rid. And the answer is mostly nothing.

Wes Bos

And the answer is lots of very complex rid. Minutiae?

Scott Tolinski

Minutiae.

Wes Bos

Minutiae. Very small things in there. So if you don't know, when you are creating a custom type, let's say, for A course. Your course might have a title, a description, relationship to number of videos, things like that. You can describe those things As we we call them custom types, but they could either be interfaces with the word interface, the name, course, And then curly brackets and then all of your fields underneath that, or it could be a a custom type.

Wes Bos

And, generally, everything you can do rid With interfaces and types, it's generally the same thing at the end of the day. We'll link off to a little rid Document that shows a very small differences between the 2.

Wes Bos

But I asked on Twitter, like, if like, what do you use by default If you don't know what you're using, because at least in my case, interface type, they almost always do the exact same thing for me. And 44% of people said they reach for an interface, 25% said they reach for a type, and then rid. Only 6% said it depends. See my reply. And all the replies were all over the board in terms of, like, these are my rules. And then somebody else would tweet back and say, this is my rules, and it's the totally opposite thing, which is is totally fine.

Wes Bos

So the one thing that I did see from people As they said, currently, TypeScript compiles interfaces much faster than custom types, so that seems to be a big reason why a lot of people reach interface first. Yeah. And it's funny. I a couple long time ago, I heard somebody say interfaces for libraries types ready for your code.

Scott Tolinski

And I have no idea the validity of that statement, but I took it and I Use that, and that's kind of what I do, based on, the I don't even remember who said it at this point, but based on what I heard somewhere one time, rid that's what I do. And you know what? It's never really become a problem for me. I know the, the pros and cons of, you know, that little rid. You posted a table in the show notes. I've seen that table a 100 times. You know, it doesn't really come into play in my day to day life. There's not too many times where I'm like, oh, I wish I woulda used an interface And so I I primarily follow that. When we when you asked this on on Twitter, I thought it was very funny. Somebody replied with, it's not called interface script, And I was I thought that was just, like, funny. It's like It kinda should be. Yeah. Yeah. It's like, yeah, it's very funny.

Scott Tolinski

Rid I largely just use types just because that's what I started doing, and I don't feel like changing it. So that's what I'm used to. Yeah. I I think your Your rule of thumb, it should be similar to how you

Wes Bos

know the difference between justify and align in CSS Grid is try 1. Rid. If you run into issue or it doesn't work, try the other one. Yeah. And that's pretty much, I think, how you should approach it. I default to everything interface. Ready. And then when I need to type for something like creating a union or I'm trying to think of what the other possible ones are, like, rid. If you wanna make a a type alias where something is 1 or another, you can just pop that into a type. An interface can't do that. But pretty much other than that, I'll just default rid Interface. And I, again, like Scott, have not run into any issues. Yeah. I wonder if at some point, they would just merge them because, like, I'm looking at this huge Document here where, like, what can types do versus interfaces? Almost all of them can do the exact same thing. And then the ones, rid Like interfaces can extend it. Classes can implement it, can intersect another of its kind. All the answers are sometimes.

Wes Bos

And I was just like, well, why not just make them 1? And we'll only have, like, one thing. I I wonder if at some point, they will make both of them be able to do Everything, and then you could just use whichever word you want. Yeah.

Scott Tolinski

Well, okay, I think that I think that, Tails leads us directly into this last segment here where we kinda wanted to do a, you know, this or that kind of thing with read. How we write TypeScript, and we've just answered the first one. And the first one was, do we write interfaces or types? Wes writes interfaces and I write types.

Scott Tolinski

Rid Neither of us really have seem to have any problems problems there. That one that one is, like, the biggest toss-up where it doesn't necessarily even matter. Re the next one was any verse unknown.

Scott Tolinski

So do you write any or unknown, Wes?

Wes Bos

Mostly neither. But, after I went through that exercise of, like, really getting at the nitty gritty of the difference, I think unknown is a little bit more safe rid Because it it makes you explicitly check the thing. Sometimes that's not always an option. So, I'll I'll sort of default to unknown, but pop an any in there if I

Scott Tolinski

Really need it. Yeah. What about you? I default to any because usually when I use something that I don't know the type of, Like, I I'm throwing it in there as, like, this is this is something that I would like to maybe, you know with that, like, winking emoji. Like, rid This is something I'd come back to later. Wink. You know? So, like, for me, if I just keep it all as any, that makes it pretty easy to find, And so that's pretty much it for me. Like, I I'm not writing a lot of stuff where the type is intentionally unknown or any. Rid. So if I'm using any, it's, like, kind of a last ditch effort to just throw it in there. And by all intents and purposes, it's few and far between. Another example would be is if you are simply just accepting rid the parameter to your function and then passing that value to, like, another library,

Wes Bos

and there's no types for it. In that case, you just say, rid Take it in. Pass it off to library. The library will will deal with that accordingly. In in that case, that's good because then you you wouldn't have to write all of the If statements to check if it if it was like, I honestly have not run into an issue in my real code where I've I've needed to read. Write an unknown and then check for all the possible options.

Wes Bos

If if you are really writing a function where it could be a string or a number, rid. Then you use a union, and you have to write them. So I don't know how applicable that is in the real world, how often that really happens. These are just rid. They're in there because sometimes you you code yourself into a corner, and you gotta ship this thing. That's really a lot of it, TypeScript. Code yourself into a corner. I don't know how to solve rid mess. It's like a Sudoku where you've hit,

Scott Tolinski

you just start fudging the numbers a little bit. Oopsies.

Scott Tolinski

The next 1 is for any with no implicit any Or implicit any allowed. So implicit any, if you don't know, is basically where the code is trying. It's trying to infer What the type is? It's trying to say, I don't I don't know what this is, so I think it's just gonna be an any. So TypeScript says it's anything.

Scott Tolinski

Now that's not going to, by default, throw any sort of problem with TypeScript, but there is a option To say, hey. No implicit any, which means that that would be seen as a use case of any or or or something that's not Not type defined, so the system doesn't know what type it is.

Scott Tolinski

I personally use no implicit any because I think if you have implicit any in your code, rid It's basically as good as it not being typed. It has no idea what it is. Right? Yeah. I agree. I have no imp no implicit any as a rule in all of my TypeScript projects because rid. I find that if you if a value is accidentally

Wes Bos

inferred or is implicitly inferred as Any, it's usually a mistake where I forgot to type the thing or the function wasn't set up properly that I didn't mean for that to happen. And then if it really isn't any, then you use an explicit any. And then you just you just type the word any in there, and then you say, okay. Rid I know I shouldn't be doing this, but I'm doing it anyway. So you type by typing the words any, it's kind of like, I accept rid The possible issues that might come arise from from doing this type of thing. So, yeah, I'm on team Scott there. No implicit any. Yes. Explicit any. Rid Cool. Also implicit versus explicit

Scott Tolinski

return types. So if you have a function, you typically don't have rid specify what the function will return as TypeScript will figure it out for you. Do you specify your return types, Wes? Not always,

Wes Bos

but sometimes.

Wes Bos

I don't have a rule where it will yell at me if I do not, but I do find it Easier for my own grok ability of the code to explicitly type what this function will return, And then that also sort of saves your bacon.

Wes Bos

Whereas if you accidentally deleted something or you you pop in a sync onto a ring. All of a sudden, it turns from returning a an order to a promise, which returns an order. If that was the case, then rid. We wouldn't have caught those. So, yeah, it's not a hard and fast rule for me in in many cases, like adding 2 numbers together or rid. Taking in a number and returning a formatted dollars value string,

Scott Tolinski

I don't need to type that. It returns a string. I know that it returns a string, and the function can rid Infer that from the code inside of it. I've gotten all explicit return types, and, I don't I don't know if I'll go back. I you know, rid I I get what you're saying about the the simple simple stuff. Yeah. I I get it. It should be pretty simple there, but I've had a I've had this solve rid. A lot of bugs for me that pop up because I'm not returning what I thought I was returning, whether that is I'm rid returning a promise when I thought I was returning your value or I thought I was, returning a a string and the thing is actually an object or whatever. You know, rid For for me, setting this when I'm writing the function has made my code practicing while I'm coding a lot easier rather than just, like, rid Maybe not like finding bugs in the future with older code or something, but if I'm writing a new function, I'll almost always like, When I'm writing the shell of the function, one of the things I'm doing when I'm determining what that function does is writing the return type, and then that makes writing the function itself A little bit more error proof. That's RDD,

Wes Bos

return driven development. It it's similar to test driven development where you you write the test first, and you write what you expected to have. I thought you were just joking with that.

Scott Tolinski

Yeah. I am. I

Wes Bos

am I am just joking, but yeah. Oh.

Scott Tolinski

Okay. Next one.

Scott Tolinski

How you compile your TypeScript? Because we have TypeScript files. Those files need to become JavaScript files to be able to be read. How do you compile your TypeScript to JavaScript? Do you use TSC? Do you use, Babel and

Wes Bos

Strip the TypeScript completely or ES build and strip the TypeScript completely? I have a couple different projects. Some of them just The smaller ones use TSC, and then the larger ones are part of Next. Js or Keystone or something like that, and they do that via the babel and webpack configs for me. So

Scott Tolinski

Both. Both. Yep. Yeah. This can often be a both. We use, TSC in our continuous integration and deployment stuff. So anytime we do PRs, it's running those GitHub actions and telling us if the TypeScript passed, but I'm mostly in development using just the straight up Stripping the TypeScript, version of it. So if you're using Babel to do it or you're using, like, what we're using, which is ES build, What it does is it simply pretends that the the TypeScript stuff doesn't exist. It removes it entirely and just outputs it as a JS file. You might be thinking, oh, that that kind of reduces some of the benefit of TypeScript. Well, actually, because we have the TypeScript checks being checked On our our PRs, but we also have them being checked within Versus Code. And Versus Code has an experimental feature, Wes, you might not be aware of that can check your entire project TypeScript errors all at once and then list them into the problems tab of Versus Code. I haven't found it to be super performant, but it exists. And, if That's a a nice way of having it. That's typically kinda what we do.

Scott Tolinski

Sometimes I'll occasionally just run TSC, no emit, just for funsies, rid Just to see if it's passing, if I'm gonna do a predeploy or something just to make sure I didn't miss anything, but we primarily strip, as the our our means of doing it. Next one is type assertion.

Wes Bos

Do you use the as or the, the tag format? Yeah. I don't even know if that's called the Tag format, but that's what I'm calling it. I use as all the time. Never use the tag. It looks like a tag. Yeah. The first time I saw it, I was like, What is that? Is that a generic on the wrong side? Or

Scott Tolinski

Generic on the wrong side of the tracks.

Scott Tolinski

No. Yeah. I I I use as as well.

Wes Bos

Only have used as, probably only will unless there's a better reason not to. Next one, arrays. Do you when you are specifying an array of a type, so an array of dogs, do you type the name of the type, rid Dog and then square brackets on the end to note that is an array of dogs, or do you type array angle brackets and put the type in between it? I do rid Dog array brackets.

Scott Tolinski

Okay. Like square brackets. I call them array brackets.

Wes Bos

Array brackets? Yeah.

Scott Tolinski

Flat flat brackets or,

Wes Bos

rid Yeah. No. Not not curly boys, whatever they are. Curly boy. Yeah. I I do as well. I never used the angle. I I think the angle brackets And a lot of these was from early on TypeScript days, and it seems like I would say most or not if not all people have switched over to using the rid The other versions. So, again, I as well just put the square brackets on the end of the type to note that is an array of that type and not a singular version of that type. Word. Okay.

Wes Bos

So what's this last one here? This last one was, if both work, like, would you use a generic or an assertion? Rid. Meaning that so I have an example here is if you are select using query selector and grabbing an element and you want that element to be typed as an rich. Video element. Mhmm. Would you use the as or the generic?

Scott Tolinski

I use the generic. Rid So query selector, all brackets, HTML video element thing. Why? I don't know. It's just kinda how I've done it. There's some things in React that make that really like, that's how you do, You know, typing refs and stuff like that, so I'm kind of used to that that format. Yeah. So that's largely how I've done it. Me too. That that's how I do it as well. And rid I think I I tweeted this out just to ask what other people say. And, like, overwhelmingly, I would say, like, 90% of people said,

Wes Bos

I use the generic because With the as, the assertion, you an assertion is overriding what TypeScript says, and the generic is just passing additional info to it. Rid. So if for whatever reason, you really goof it up and you pass something that's not a valid generic, then it will still error out for you, whereas the assertion is like, alright. You know best.

Wes Bos

Keep going.

Scott Tolinski

Yeah.

Scott Tolinski

Well, that is, that's really, really interesting. It's it's funny how, You know, you and I talk so much about code, and we still do so many of these things differently. And at the end of the day, it doesn't matter. So, like, If you're the type of person who's waffling back and forth on some of these choices and, like, you don't, just go for it. It doesn't it doesn't matter. Many of these are just about fine except for, some of them, like the no implicit anything, might save your bacon a little bit as well as explicit returns might save your bacon, but the other ones are mostly just preference. Rid. Yeah. I think that we're we're pretty clear on

Wes Bos

when something doesn't matter and when something is probably a good idea, and we'll explain ourselves. So let's get it. Scott and I are not ever overly opinionated about sometimes. And that was that was a scary thing to me when I first got into coding. You would you would come across somebody, and they would have these very big rid Absolutes of never use this. It's bad practice.

Wes Bos

And then I would just be like, why? But but why? Like, what's going on? Like, why is that awful? Like, why is it even part of the language of it. So awful. You know? And and then you realize, like, oh, these these people are just jerks, and they they don't know how to Properly convey the whys and hows above around their opinions.

Scott Tolinski

Yeah. Yeah. That is really kind of it. Right? People rid. Instead of saying, like, this is a way of doing thing, it's like, this is the way of doing no. There's just a 1,000,000,000 ways of doing things, and what was it? I I, like, tweeted out about, rid. I actually deleted the tweet, but I had tweeted out about Notion being slow because it didn't slow.

Scott Tolinski

And, like, people took that as an opportunity to, like, slam dunk Or not even slam dunk. What would that be to the hip check to their their least favorite technical practice or or a coding library to blame it on Notion? They'd be like, Well, that's what they get for using a newfangled data band. Like, it's not about the tech used. Most of the time, it's not about the tech used. Okay? You can do a lot of really great things with not on any tech, but you can do a lot of great things with lots of tech. So using Node for this or using Mongo for this or using PHP for that, it doesn't probably matter at the end of the day, and it's more or less like the practices that you use along those things. Yeah. Honestly, unless you're using Angular, It doesn't matter. Unless you're using no. I'm just I'm not gonna go there. No.

Wes Bos

Just joking. Just joking. Let's get in some sick rid Picks, do you have a sick pick for me today? Yes.

Scott Tolinski

I do have a sick pick. I recently, went all in on rechargeable batteries because I rid I don't know about you, but we got a lot of batteries. Our TV remote, we have a Samsung TV, and the TV remote uses Bluetooth so you don't have to, like, point it at the TV and it, like Oh, nice. The downside of that is batteries last like 10 seconds long. The batteries, every single day, we, like, come into the house and they're like, oh, the the remote won't Bluetooth connect again, And it's always the batteries. So I I went pretty ham in on some rechargeable batteries, and I got this like, so many of these rid battery chargers are, like, 4 batteries. Like, okay. Doing 4 batteries at a time, not a really not a go for me. So I got this Power Roll, And it's the circular battery charger that does 16 rechargeable batteries at once, and it does rid Triple a or double a so you can do both of them all in one.

Scott Tolinski

And so I have been using this for a little bit to recharge 16 batteries at once, and, I really, really, really like it. Now I'm I'm going to only use rechargeable batteries for literally everything in our house, and rid We'll always have 1 available because with 16, that's not you're never gonna be replacing 16 batteries at once. Oh, that's Cool. It it's also just like a good way to store

Wes Bos

your batteries as well. Yeah. I like it. So far, I've had it for a week, but I'm already I'm already digging it. Rid That's cool. I went down this rabbit hole a while ago, and I opted not to go rechargeable because our kids rid Well, the basically, the batteries are for kids' toys in our house and, like, minor thing. Actually, my mouse no longer takes batteries, which is nice, and my keyboard doesn't. I used to rid Be on a old keyboard and a mouse, and I would go through them like crazy. Oh, yeah. And, I'm waiting for our kids to get out of those, like, toys that make sound Because I'm worried that, like, we things get left in the rain or donated or thrown out, and and I was like, no. There's, like, rid $6 worth of rechargeable batteries in there.

Wes Bos

Don't do it. But I definitely wanna go down that route. That seems pretty cool. Same with, like we have the, Nest smoke detector.

Wes Bos

And if you put, like, regular batteries in them, their regular batteries are, what, like, nick nickel cadmium, I think.

Wes Bos

And they're not for whatever reason, they don't put out enough wattage or I don't even know for the the smoke detector. So we have to go buy these Super expensive lithium energizer batteries Mhmm. Which is silly.

Wes Bos

And I'm wondering, oh, could you just use rechargeable lithium batteries in them instead rid and then not have to throw them in the landfill once a year. It's like it takes, like, 9 or 8 lithium batteries.

Scott Tolinski

Yeah. Rid There there are some things in our house that just, like, eat through batteries. I I play a lot of VR. The controllers use double a batteries that the kids got these turtles that Turtle lamps that play music. They take triple a batteries. You gotta unscrew every time because you can't have kids open them up the batteries.

Scott Tolinski

It's like I'm constantly replacing batteries around this house. That's my my main job here as a as a father is the battery replacer.

Wes Bos

Rid. That's awesome. Well, my tech pick has to do with batteries as well. Woah. And a while ago, you mentioned you have electric toothbrush. Right? Hell, yeah. Hell, yeah. Which one do you have? Oral B maybe? We've had we this is our 2nd one. We've we've we've had I've had electronic toothbrush. That's before I can remember just because they they're so good. They're so good for your teeth. I can't believe that I waited so long to get one. So rid. I went to the the dentist again. I got I got mentally berated by the dentist about how I need to be getting electric toothbrush. Rid. Finally, he's like, alright. I'm gonna do it. And then I they're like, there's there's 2 types. There's the the Philips Sonicare, and then there's the Oral B one. And I was like, okay. But these things need they either have this, like, massive dock that you need to put on your your countertop and plug into the wall. Oh, I'm sorry. We have the Sonicare.

Wes Bos

Rid Okay. The Sonicare is a really nice one. So I found this, like, new one. It's called FairyWell, and they have A whole wide range of of different types of brushes, and I went for the the most expensive one. It was, like, $50.

Wes Bos

And this thing is amazing, and it it sorta ticks all my boxes because the battery in it lasts for they say it lasts for 30 days. Read. I'm going on about, like, twice a day. I'm going on right now 26 days, and I rid. I didn't even charge it when it came out of the box. I just turned it on, and it's still going strong. And, apparently, the thing charges in in 4 hours. And that that was big for me because I was like, I rid. I don't wanna have to have, like, a dock where I charge it all the time. I'm gonna forget to charge it or whatever. So this thing is just use is USB charge, And it's good for 30 people online. We're saying 40 days. Sometimes it will it will go for.

Wes Bos

And, man, I can't believe how Clean. It makes my teeth feel it makes me feel like I went to the just went to the dentist because it's like, like, ultrasonic almost. Ready. Yeah. And it has really cheap brush replacement heads. It came with, like, 8 of them. And I was like, man, this is this is the thing to get. I'm just looking at it right now. It's $38 US. And I'm kicking myself for not doing it. The only thing I don't like about it is I I mentioned it's USB charge, but the plug connector that actually goes into the toothbrush It's not a USB. It's like a phone, Gary? Or what? Yeah. It's like a it's like a headphone jack. So you gotta, like Mhmm. If you rid If you go traveling, you don't unless you're going traveling for over a month, you don't need to take it with you. But at the end of the day, I know that at some point, I might lose rid This little USB to headphone jack thing, and I won't be able to charge it. So I'm like that's the only the only downside to it, but everything else has It's been great, so I'm super happy with this one. I waited, like, a full almost a full month before I sick picked it to make sure that it was pretty good because you can never You can never trust the the Amazon reviews. You know, like, my wife always comes to me. She's like, it has 4 and a half stars on Amazon. I was like, everything has 4 and a half stars on Amazon. Rid Yeah. Unless somebody's paid bots to leave negative reviews so that other people buy another product. Yeah. I could not trust anything less than Amazon reviews unless, of rid There's, like, somebody with, like, a picture or I don't know. Man, I do not trust them at all.

Wes Bos

Yeah.

Wes Bos

I went down toothbrush YouTube.

Wes Bos

There's a couple of really good electric toothbrush reviewing dentists out there, and, you can tell they're not being paid off by big Big toothbrush.

Scott Tolinski

Yeah. Big toothbrush always getting in the way of our quality products.

Scott Tolinski

They're just trying to shove oral b down our throats. Our toothbrush, our Sonicare, is so like, it's a fantastic toothbrush, but to charge it, you put it in a glass that sits on a wireless charger. So they give you a, like, a a glass a physically glass rid Like a little shot glass? Like a little shot glass and then put a wireless charger in there. So instead of just sticking on the thing that sticks it straight up, You put it in a glass because it's, like, trying to be like, oh, you know, that's what people do with their normal toothbrush. You're like, I don't want your crappy glass, and I don't want your your wireless charger.

Scott Tolinski

Just put it in a cradle or or something or a plug in or something would be so much better. Courtney and I hate the stupid glass because we're always having to clean it, put in the dishwasher. It's like, why? Why? Re We had the old old version of this that charged it a normal way by just, like, putting it on a stand, and it's like, that was Way more simple. Why why you gotta get too cute with it? But, you know, that's what they did. Whatever. Give me USB c, And let me be able to charge my MacBook and my toothbrush Mhmm. Once a month on the same thing, and then that that's it. Yep. Here's what I want. I want detailed analytics of how of each of my teeth, how much time I've spent with the toothbrush on each of those teeth.

Wes Bos

I want want full reports Sent to my my dentist. Yeah. Honestly, like, there was once a Kickstarter for this, like, this, like, thing you put in your mouth, and it just.

Wes Bos

Rid It was so good. It was so goofy looking. Yeah. But, like, I was like, I want everyone's like, that's silly. I was like, I kinda want that. I wanna be able to go on Twitter for 3 minutes I just put this thing in my mouth,

Scott Tolinski

but I don't know what happened. I didn't even look into it. I I assumed it would be more popular if it actually works. Yeah. I would assume it's probably just not working. Well, this was the Colgate toothpaste hour with, Wes and Scott here. So I hope you enjoyed that. As always, let's get into shameless rid plugs. I'm going to plug the latest course on level up tutorials, which is node fundamentals part 2, authentication part 2, and we dive into a whole host of topics rid. I really talk about some of the things that we couldn't get to in the first part of this same series that we released in February.

Scott Tolinski

We talk about verifying emails.

Scott Tolinski

We talk about the process of, you know, you sign up for an account, that email needs to be verified. What do you do? We talk about the changing your password flow, Creating those tokens, sending the email so that only the person who clicked to change that password has access to change their password. Right? And we also talk about things like two factor authentication, where we even generate QR codes live on the front end and use them with that, you know, James Bond rid Timer ticker offer thing where you have 6 60 seconds to, sign in before the whole world blows up. We implement that using Just straight up no services, just basic node, node libraries here and there. But for the most part, like, when I asked on Twitter about what rid 2 f a solutions people are using in node. I got a ton of people just saying use this service, use that service, whatever. And while services might be the way to go in your project, It's also really not that difficult to program. So, we talk about the ins and outs and the fundamentals of what it actually would take to program a thing, and we find out that it's really not that hard. So, level up tutorials .comforward/pro.

Wes Bos

I am going to sick pick beginner javascript.com.

Wes Bos

Rid. This is a fun exercise heavy approach to learning modern JavaScript from scratch. And whether you are totally new to JavaScript Or if you are intermediate and you wanna fill in any holes you have, check it out, beginner javascript.com.

Wes Bos

It will get you up to speed. You'll also have a whole bunch of fun Writing and learning new JavaScript things. Check it out. Use coupon code syntax for $10 off. Again, beginner javascript.com.

Scott Tolinski

I was thinking about doing a course last where I do rid. 31, projects in 31 days for JavaScript.

Scott Tolinski

You think that'd be cool? That's my javascript30.com.

Scott Tolinski

I know. I know. I'm just I'm just rid Just joking.

Scott Tolinski

It's it's in vogue.

Wes Bos

You should one up me. Yeah. I own a couple of the, like, competing. I think I own heating. I think I own css30.com

Scott Tolinski

and whatnot. Oh, that's fun. You might as well. Right? That's that's a nice little brand thing. Yeah. Well, I knew people would be like, oh, I'm gonna do that, but for Something else. Yeah. Just take the West idea. Was it that not 8 minute abs, 7 minute abs?

Wes Bos

That's great. Alrighty. Well, that's it. Thanks for tuning in. Catch you on Monday. Peace. Peace.

Scott Tolinski

Head on over to syntax.fm for a full archive of all of our shows. And don't forget to subscribe in your podcast player or

Wes Bos

ready.

Share