 Hello and welcome to my talk about TypeScript, JavaScript and your brain. Hi. I'm Peter. I'm a trainer for front-end web technologies. Whenever there's no pandemic going on, I'm usually traveling all around the continent to teach people about the latest in browser APIs. This includes HTML5, JavaScript and also TypeScript sometimes. There's a bunch of blue stuff on the screen right now. This is where you can follow me online. There's a blog you can read. There's tweets you can follow. I'm on a podcast called WorkingDraft. That's mostly in German, but we do English episodes sometimes. And you should also check out my site project Warhol. Warhol is a tool for automated design testing right inside your browser. If automated design testing in your browser with a browser extension sounds interesting, check it out because we are going to launch in just a few weeks. But today's topic is TypeScript. What's TypeScript? Well, according to Wikipedia, TypeScript is an open source programming language developed by Microsoft that's a strict syntactical superset of JavaScript and that adds optional static typing to the language. Well, what's all that about? Let's look at a practical example. This is a simple function that takes RGB values as its input and returns RGB values as its output. It converts colors. It turns white into black, black into white and so on. This is a JavaScript function, but it's also a TypeScript function. TypeScript is just like JavaScript, but with a few extras. In JavaScript, we can write the function just like this. In TypeScript, we can do so as well. But in TypeScript, we can also add additional information. This additional information usually takes the shape of type annotations, where we definitely define how the types in our program should look like. Invert, in this case, probably wants to work with numbers, but nothing in this program says that it can only work with numbers. But once we define an RGB data type, basically say that any RGB value must consist of three numbers, we can add type annotations to our function. This tells the program that Invert must always get an RGB value as its input and that it must also always return an RGB value as its output. And that's the only way this program is valid. If we then call this function and provide some input, the TypeScript compiler that takes TypeScript and turns it back into JavaScript can verify that the program makes sense. And indeed, in this case, it does make sense. Invert in the last line gets three numbers as its input and we expect an output of three numbers, which is also provided by the function. If our program doesn't make sense, if, for example, we replace the last number with null, which is not a number, so this program doesn't work, TypeScript will not turn this into JavaScript, but will instead complain with an error message. So TypeScript, once we've written a program that's valid, that works, that satisfies all of our types constraints, turns this back into JavaScript and we can actually run this in our browser. The debate about TypeScript and JavaScript usually looks like this. There's the fans of JavaScript that say dynamic typing like in JavaScript where you don't have to deal with type annotations is easier to develop. Maybe you're faster and static typing might lead to more correct programs, but it takes a lot more effort. And I don't know if this is true and I don't know if it is true, how important this distinction is. I'm more interested in another question, mainly what does TypeScript do to your thinking? And based on this, we can talk about whether you should care about TypeScript or not, but I'm not really interested in quantifying the advantages or disadvantages of TypeScript. I'm more interested in what it does to our brain. And this may be an interesting question even if you already are a die-hard TypeScript fan because it recontextualizes your use of TypeScript, maybe. So what do I mean by due to your thinking when we are talking about programming languages? Let's take a look at some JavaScript to set up my argument. This is just a bunch of numbers. Let's say we want to create a sum of all the even numbers in this array. There's two ways to go about this. The first is the imperative programming approach. We basically create a new sum variable called sum in this example, and then iterate over the array and for each even value, we add this value to the sum. This is imperative programming. We create some data like the sum and then we just mess with the program, mess with the data until we are done, until the desired end state has been reached. But there's also another approach, the functional approach. Functional programming, well, it deals with functions, but the most important bit is how we treat data. In this case, new data comes from old data. We describe functions that transform our old data, our inputs, our numbers into a new data, in this case, our sum. We do this by first filtering out all the non-even values and then taking the remaining values and then summing them up. There's no data that's being manipulated here. We just describe how we get from one bit of data to the next bit of data to the final bit of data. And this is how functional programming works. Both of these approaches work in JavaScript to some extent. And you might have come across the problem with that when you've dealt with asynchronous code. In the olden days, back before we had promises, we had to work with callbacks whenever we had to do an asynchronous operation. A function like do stuff might take a long while, but we can't do stuff that takes a long while on JavaScript's main thread, we have to be asynchronous. And this means passing functions into other functions like do stuff here. This callback will get called with a result or an error depending on the outcome when do stuff has done its, well, stuff. And this is quite a mess. It leads to spaghetti code and it also mixes the paradigms. We have bits of functional programming here where we pass functions into other functions, but inside our callback, we do basically whatever. We use imperative programming language constructs like if and else. This changed once we got to promises. JavaScript got promises a few years ago and this turns the way we work with asynchronous code into something that's basically pure functional programming. In this case, we call do stuff and then don't have one huge callback function that handles the errors and the side effects, but we chain operations and define transformations over data. How do we process the result? Well, we shove it into this function. How do we process an error where we shove it into this other function? This is a fundamentally different approach how you handle data. And even promises are out today because we have async functions. We have this await keyword that we can use in async functions to basically get rid of functions altogether. There's no callback involved and there's no promises anymore. It just looks like regular code, like imperative code. So we had callbacks back in the olden days, then came promises, then came async functions. These are just features, but what do they do to our thinking? How do they influence the way we write code? Well, an async function according to MDN is a function that leads to a cleaner style. This is at least what people say, but what actually is a cleaner style? A cleaner style is a value judgment. This doesn't really describe anything. It describes how we feel about using async functions. And I believe it comes down to having one paradigm and not being forced to do constant context switching. If we have our callback functions, there's no particular style enforced. Sometimes we have to write callback functions and shove functions into other functions, kind of like functional programming, but not really because in the callbacks themselves, there's imperative programming all around. Then there were promises, which is sort of an opt-in to nice and clean functional programming as far as that's possible with JavaScript, which is not very possible because JavaScript while functional programming isn't strictly speaking impossible, JavaScript is not really meant for functional programming. The important bit to remember here is that there's no way out of callbacks really because asynchronous code in JavaScript has to be processed off the main thread. We need some way to schedule operations. And this usually means dealing with functions, except when we have async await. Because with async await, with the await keyword right here, there's no function involved and we can use pure imperative programming. We don't have to context switch between imperative programming, which is what JavaScript is good at, if else for loops try catch and so on, and functional programming, which is not really JavaScript's strong suit, but it's something that we have to deal with regularly when we do asynchronous code, except when we have async await. Async await feels so liberating because you don't have to switch between two different ways of programming constantly. You can just stay inside your imperative world, which is where JavaScript is best used for. So this is what async await really does. It makes pure imperative programs possible and this eliminates a whole bunch of mental overhead. This is what it does to your brain. It feels liberating because it is liberating. You don't have to deal with functional programming and with callbacks anymore. And you don't need to be aware that this is what is happening. You don't even need to know that functional programming even is a thing to reap the benefits. It just feels much simpler now because it eliminated a whole class of problems, a whole bunch of mental overhead from your day-to-day programming. And TypeScript can do something similar. So let's talk about our invert function again. What can this JavaScript function do? Well, it can invert colors, probably, obviously. But this is something that we just know because we have written the function or maybe we've read the function. It's called invert. It takes something called R and G and B sounds like it's meant to invert RGB colors, but how do we know? How can we know that this actually does work? Well, in JavaScript, you would usually just write a bunch of tests. So we would expect black to be turned into white. We would expect white to be turned into black. And then we maybe add a few more tests and maybe even more and more tests depending on how paranoid you are. But if you write JavaScript and if you write tests, there's going to be somewhere in your test writing the point where you say, this is enough, this should do. I'm certain that this function now works as expected. Let's say we place this cutoff here right at the third test. In this case, we have three examples in our test that we've confirmed to work. Three colors that are being transformed like we intended them to be. But this being JavaScript, there's in our code not actually a way to enforce that the values RGB are actually numbers. So this is another case that might conceivably happen. We might pass in a string instead of a number. And this may work, may not work. I think in our code invert as written, this actually works. The string two is treated as the number two. But what about this? Should this work? If my JavaScript type knowledge isn't wrong, this should probably still work. But this will probably break in some awful way. But this isn't really broken because we haven't really defined that this is not anticipated usage of the invert function. This is more or less undefined or unconfirmed behavior. It's not wrong. It's just something that we haven't thought about. The problem with dynamic typing is that we can write all the tests we want, all day long. There's going to be some point in our development process where we say this is enough. I'm convinced that my function works as expected. So from three or maybe more examples, we infer that there's a whole bunch of values for which our function works. And everything outside is simply unverified, undefined. We don't care about it. And we cannot care about it because the possibilities are endless. There's got to be some point where you stop writing tests. There's going to be permutations of RGB inputs that you just don't consider because it would be totally exhausting to do so. It's necessary that there's unverified spaces in your program, that there's inputs that you haven't considered. And this is not to say that all the inputs are wrong. Maybe they are not, but there's nothing in your program that says anything about the unverified space. But if we are really honest with ourselves, even the okay space in the middle isn't really verified. Tests are just examples and we infer that there's an okay region in our program from this, but there's not really any basis for this. So in essence, our program consists of a whole bunch of undefined behavior. And we have three examples that convince us that the function works as intended. This is always the case in dynamic languages. Programming in dynamic languages requires some leaps of faith because at some point, you are going to stop writing tests. You cannot write tests till all eternity. Now, how is TypeScript different? It is different, but it's probably not different in the same way. But it's probably not in the way that you expect it to be different. So, let's go to our TypeScript function. Let's say our invert function RGB has its type annotations and has now a much more narrow-defined space of inputs that can actually go into this function. This function is meant to convert RGB colors again. And how do we know that this works? Well, again, we can write some tests, but we can also say, well, it has been defined to work. We have defined what a valid RGB input is, three numbers, and the function has been defined to only take RGB inputs and produce RGB outputs. So, anything else is simply not a program because if we, for example, try to shove null into invert, the TypeScript compiler will simply not produce a JavaScript program that we can run. So, there's no way to define a program to build a program that violates our type expectations. So, our program has been defined to work, even if we recycle our tests from before that confirm these three particular cases, we can be sure that everything we've talked about afterwards is simply out of scope. This is impossible. There can be no program that looks like this because the types don't allow this program to be compiled by the TypeScript compiler. So, this is gone. This is no longer our problem. But, there's other values that might conform to our types, but they, that may still be a problem. How about this? Well, probably the RGB values can be at most 255. So, 500 is a valid number, but this is somewhat out of scope. This is not defined as well. How about this? Negative numbers. This is not defined. And not a number in JavaScript is actually of the type number, so this, again, is a valid program in the sense that not a number in JavaScript counts as a number, but still is something that we haven't considered. So, if we go back to our circles, to the examples with the tests and the unverified space in the dynamic language, adding types to the language eliminates parts of the problem. And the problem that's being eliminated is that the unverified space becomes impossible. It's no longer unverified, but it's impossible. Programs cannot happen inside this impossible space. But what we also need to consider is that the okay space here is still just based on our assumption that our few examples lead us to believe that this will be okay according to our type system. But as we've seen, there's inputs that do confirm to our types because the type categories are not as fine grained as we'd probably like them to have. So, again, this okay space is a lie. It's an illusion. The okay space is also unverified. The only verified properties of our programs are those where we have concrete examples, the tests. So, if we compare the dynamic language to the static language, then the only thing that really changes is that a large space of the possible inputs that were unverified in the dynamic language are impossible in the static language. So, they are not part of the problem that we have to deal with. But there's still the unverified space in the center. And that's the same for the dynamic language and for the static language. It's probably a bigger space in the dynamic language in the sense that we can pass in nulls and so on into the RGB array. And this will probably work or not work or fail or explode in some way. But in the static language, the reactions on this are still possible. I can pass in numbers that are not conforming to my expectations, that are too large, too small, not a number, infinity, what have you. So, what this basically brings to the table is that what a static type system does for you is it allows you to ignore more of the cases that you did not think about in the first place. This is what it really does. Does it make your code more correct? Well, maybe sometimes. Does it eliminate a whole bunch of problems, provide better tooling? Yeah, yeah, probably. But what it really does, it reduces the amount of undefined in your program. It doesn't eliminate it. Remember, there's still this large hole in the middle of your program in any case, no matter if you're writing in a dynamic language or in a static language like TypeScript, the unverified space in the middle is always there. But there's this whole outer ring that you don't have to care about anymore. And probably in most cases, you aren't even aware of the outer region or at least not consciously aware. A static language like TypeScript eliminates this outer region and so again reduces your mental overhead. And this is why programming in a static type language, if you're comfortable with that, feels a little bit liberating, feels easier because there's a whole class of problem that you cannot have. But it's important to remember that there's still no silver bullet. There's still undefined regions in your program and they may be larger than you think. So a type system doesn't eliminate all the errors, it just removes all of the problems that you probably didn't even think about. And of those that you think about, many are still there. You do not need again to be aware of this to reap the benefits. If it just feels a little better, well, that's a win anyway. But this is really what a type language does to your thinking, at least in my mind. So what can we take from this? Is this useful? Is having this mental overhead that we probably weren't even aware of in the first place is removing this really helpful? I would say so because any reduction in mental overhead is worth considering. Today's programs in front-end and back-end with JavaScript and Node.js are so fiendishly complicated that any reduction of complexity is something worth considering in my mind. And there's also the fact that there's other benefits to static languages like better tooling that may also nudge you towards TypeScript. Are there downsides to TypeScript and other statically typed languages? Oh boy, definitely. You have additional build steps. You need to work with the TypeScript compilers. There's dependencies. Newer versions of TypeScript can break. Maybe you have to install third-party type definitions and there's a bunch of type system rabbit holes that you can fall into. If you are like me and you really wanna make sure that your program is as well defined as possible when there's many an afternoon that you can waste just simply working with a type system, defining types, making sure everything is covered and then suddenly the working day is over and this is not really that useful when it comes to the bottom line. Is TypeScript the future? Should I care about TypeScript in the future or in the near future? I think so. For the moment, it looks like TypeScript is eating the world. But tastes are bound to change yet again in my mind. They have been compiled to JavaScript languages before, if you think about stuff like CoffeeScript and they're going to be new ones, especially with WebAssembly. So if you write TypeScript, it's probably not going to be code for eternity in contrast to JavaScript, which will run in any old browser till the end of the universe. But again, for the foreseeable future, TypeScript is something that people are gonna use because there's upside, even though there's also downsides. But the important bit is really to understand the downsides. I think the downsides, build steps, dependencies, the type system rabbit holes, this is something that every programmer can in some way relate to. And the upside is also important to consider because what aesthetically typed language, apart from all the tooling really does for you, is to reduce your mental overhead. It makes the leap of faith that you have to do a little bit smaller. It doesn't eliminate the leap of faith, mind you. The only bits in your program where you can be sure that they work as intended are those bits that are confirmed by proper testing. And the type system can simply make a bunch of inputs impossible. There's always a leap of faith involved when you say this program is done. The only question is, how big do you want your personal leap of faith to be? Thank you for your time. Read my blog, write emails, and follow me on Twitter. And I'm happy to receive your questions now. Thank you. Hi, we're back. And we are also not alone. Peter, are you here with us? Hi. Yay. Oh, I'm gonna, oh, okay. Ah, hi. Now it works. So, Robert already just posted on the chat that as a JavaScript newbie, he will have to rewatch your talk on half time because it was interesting, but fast. Yeah, but that's normal and this doesn't really have anything to do with him being a newbie. This has to do with me talking really fast. That's just how it is. I get that a lot too. So, straight from your talk, type, what rabbit holes? Type system rabbit hole. Type system rabbit, what is a type system rabbit hole and where can I get one? I don't think you want to have type system rabbit hole. How do I say this without going too much into detail? Type scripts type system is very dynamic in a sense and you can write down types like I did in my example with a simple RGB type, but you can also create new types from existing types. Basically define a bit of base truth and then derive all your concrete types from that by doing a lot of transformation and mucking around with types. And this just with any abstraction and software can lead you into directions where you, once you're in there, figure out that you really didn't want to be there in the first place. That's the type system rabbit hole. Okay, I have a question coming in from the headquarters that I want to ask before I follow up with my next question. So type fester, the question is, do you expect JavaScript to implement most if not all typescript features in the long run? I expect JavaScript to implement exactly zero of typescript features in the long run. Well, there's a bunch of reasons for this. First of all, that simply the goal that typescript has is a completely different tool, a goal from JavaScript. And typescript is a strict syntactical superset of JavaScript, but not every JavaScript program is a valid typescript program. And every browser has to support every bit of JavaScript that has ever been written from the start of time until today. And if browsers were to implement typescript features in JavaScript today, they would break existing code and this will never happen. Also, there's really no need to implement this in JavaScript because we already have the features we want in typescript. So if you need types, if you need all the fancy features just use typescript and compile it down to JavaScript. Everybody wins. Yeah, I just have a comment coming in that this is the highest information density interview ever. Wow. I have another question. So do you expect to ever have, do you expect to see not a number ever being not a number? No, not a number is a number and this is perfectly fine and totally reasonable if you read the specifications. So that's not really useful, not a number being a number, but it makes sense in many different ways. And just not in the most intuitive sense if you're not a programmer, but that's true for most of programming's terms and features. Can we petition for a name change then? Like really not a number or something like that? Probably. I mean, I always see it like this. Not a number is a number, just like infinity is a number in JavaScript. Both are numbers in the technical sense, but both are not useful at all. So not a number is basically just a third kind of infinity. We have positive, infinity, negative, infinity and not a number. All three are just broken numbers, broken in different ways. I really hope that you can hear the backstage laughing. Okay, so turning away from jokes about numbers and not numbers, you're a trainer, right? Right. Now we've gone through a time where especially one-on-one training would have been very difficult. How has COVID-19 affected you? Have you turned to virtual trainings? I haven't really. Right now I'm basically draining my bank account over time and I'm totally not in any situation where this is a problem in this year and I also do stuff on the side. I write articles and stuff, but virtual trainings are a different beast and I haven't yet figured out for me how this could work and also the companies that I would do these trainings for, they are also affected by COVID-19 and they either have way too much to do because they do, I don't know, video conferencing or something or they are part of the rest of the economy and they have other problems on their hands right now. So it's basically just there's not much going on apart from a few conferences like this one. I have made very good experiences with big blue button except for the name. Try that. In the, no, I was more talking about not the technical solution, how can I do this whole video chat thing because as you said, this is a soft problem and there's other software as well, but it's more the whole way I built up my, how it works. We talked about information density and me talking really fast. This works kind of if we are all in the same room together, but over remote this gets probably really just tiresome and I don't get the feedback that I need for my numerous digressions that I usually have in my slides and in my workshops. So I don't think this really works for me, but this is more down to how I do workshops and talks and not so much a technical problem. So I just rather wait out this whole pandemic thing and then go on like before maybe. Okay. And then you were there for NaosCon last year, right? I was, yes. How did you like that? I think the right word is I was really impressed. I was impressed with this being a rather, you are mostly a small community compared to others and the conference is rather small compared to others, but size isn't everything and the sheer quality and the effort that obviously went into this conference. I was really impressed by and I've seen a lot of conferences in my time. Nice. And then during your talk, we had lively discussions going on here, wondering if you are a trainer as you claim you are. How do you like, you're so on top of very modern technology, do you work as, do you program on the side? Are you actively involved in developing or maintaining projects? Is that a thing that's still going on for you on the side? In a very small sense, yes, but not really all that much. I mean, it always looks like I know everything, but this is just because I pick the topics, really. Clever. And there's a whole lot of stuff that you have to concern yourself with if you work on real projects, mainly your customers' concerns, for example, so supporting old browsers, which is two bits of information that I really know nothing about. If anything breaks in Internet Explorer today and I have to fix it, I probably won't be able to because I haven't done anything like this in 10 years. I just cry. No, I write. Yeah. I just cry a lot. I'm back in the day when I did do projects, I always just went for a run whenever something broke in Internet Explorer that had to. No, I write my own software and I have, no, my knees are too broken for this kind of challenge. No, no. But I do write my own software, the slides, the code animations that you saw on the slides. This is all my own in-house software. It's not the greatest because it's in-house software and did never have to answer to any colleagues or quality control or customer wishes or anything. And there's also a Warhol, which I think was in the slides after my introduction where we do design testing in the browser. We are going to launch in a few weeks, so check this out if you want to. And this is something like diving into browsers and fixing bugs and trying to figure out why is this red and not blue like it's supposed to be. So stuff like this, it's not really customer oriented. It's not an everyday regular project because it's still extremely specific and extreme close to browser APIs themselves. But this is how I stay on top of things. I write my own stuff basically. Very cool. Peter, thank you so much for this very high density interview. Thank you for having me. It was a pleasure. Hope to see you again next year. You definitely will. Awesome. I'm already looking forward to it. Me too. Thank you very much, Peter.