Production-Grade TypeScript Tests for Types
Transcript from the "Tests for Types" Lesson
>> It's important to realize that type information, these interfaces. This assertIsTypedArray thing that we just made in the teams file, right? Assert is typed array, this needs tests just like anything else needs tests. And it's a different kind of test to write because the type information is not imperative code that's executed line by line by line by line.
[00:00:31] [LAUGH] The way I think about it, it's like a balloon animal where if you squeeze one side, the other side puffs up and you squeeze the other side, so there's no sense of ordering. It's more, we check to make sure everything is lined up in one step. There's no time aspect to it in terms of some things are executed before other things.
[00:00:51] It's just a set of constraints. And in one big step, we see if everything lines up. So it's a little counterintuitive to debug things just because we're not used to thinking about code in this way. However, tests are a great tool, both in terms of protecting your code from regressions.
[00:01:12] And in terms of getting to the bottom of mysterious problems by sort of taking a big chunk of things that are not working and sort of doing a bisection search where you write some tests because you know, okay, this works, or this case here has to work. Write a bunch of tests and then you can sort of narrow down where the cause of the problem is, as you attempt different fixes.
[00:01:41] So tests are really, really, really important aspect of a healthy TypeScript project. Of course, you can write tests in TypeScript. Like we have these tests written with Jest but these are only positive test cases. They're things that should work and do work. It's really hard with this existing tool to write things that shouldn't work and must not work.
[00:02:15] These kinds of tests are important too, the negative test cases. And if we were to just throw those in to Jest, into the test suite for values like react components, the compiler would break, it would say, I can't run your tests. There's a compiler error, right? Doesn't really give us a great way of doing that.
[00:02:36] I reach for two tools, and I'm not, in some ways they're two choices, you could use one or the other. I use both because one is better at some things and the other is better at other things. And I think that both together give me the confidence I need to make sure that my really complicated types, when they're unnecessary, they keep working.
[00:02:58] And I'm alerted as early as possible when things break. And here's something you need to know about TypeScript. It doesn't follow semantic versioning. Every middle digit release of the TypeScript compiler which happens about every six weeks, these days. That introduces breaking changes and the TypeScript team, their position on semantic versioning is they believe that there's no such thing as a truly non breaking change.
[00:03:32] And oftentimes they will fix bugs that cause other people's code to break. Now, this is not to say that they're acting irresponsibly or they're bad, but it's just the reality of the way this project is managed. And I've never built a competing thing to TypeScript. So I am not saying that there's definitely a better way and they should do this the better way.
[00:03:56] I'm just saying there's risk, every compiler version, every middle digit release comes with breaking changes and they publish a list of them. And some of these are really hard to figure out. So what we're gonna do here is we'll set up this test suite and part of this is gonna let us run our code against nightly TypeScript builds.
[00:04:16] So if you look at the workshop project itself, and go to this Actions tab. You'll see that I have a couple different jobs here, right, I've got code, security issues, image minification. This one second from the bottom, this is TypeScript at next tests. And you can see every 24 hours I'm pulling down the latest nightly build of the compiler.
[00:04:40] And I'm making sure that it continues to work with this project. Because I wanna know about whether something's gonna break when it lands in master, on the TypeScript project, because I can then try to see, was this, did they introduce a bug that I need to tell them about?
[00:04:59] Or was I depending on the existence of a bug, right? So you can use GitHub actions to set up a cron job effectively, which every 24 hours will make sure that the latest nightly build still works with your project. Super, super valuable as an early warning system, so you don't find out when everybody else is taking an NES release, like greenkeeper or dependabot, it's going around upgrading all the open source libraries and your stuff is breaking.
[00:05:29] It's a really urgent problem at that point. It's very valuable to know about this well in advance.