The Story Behind TypeScript
Daniel Rosenwasser, the program manager for TypeScript, discusses its history and growth.
In the beginning, TypeScript was being worked on by a small team and was competing with other libraries. But when Angular adopted TypeScript and the teams began to collaborate, growth really started to take off.
Daniel also talks about the development of TypeScript, including how features like index access types, mapped object types, and conditional types were added by working with developers to understand their needs.
Matt Pocock: [0:00] What's up, wizards? I'm here with Daniel Rosenwasser, TypeScript's program manager for oodles and oodles of years. Boss of TypeScript, king of TypeScript...
Daniel Rosenwasser: [0:12] [laughs]
Matt: [0:12] I don't know really what the terminology should be, but extremely nice man of TypeScript.
Daniel: [0:17] I don't think I get that title of royalty just yet, but [laughs] I've been...
Daniel: [0:22] the team for a while now.
Matt: [0:24] A long time. I'm really excited to talk to you about TypeScript's direction, TypeScript's past, the decisions that flowed into making TypeScript what it is today because you've been with TypeScript for over half of its journey.
[0:37] At the time we're filming this, TypeScript's been around 10 and a little bit years, I think, past a decade. You've been with it seven years at this point, or nearly seven years?
Daniel: [0:47] I'm going on nine years, actually.
Matt: [0:49] What?
Daniel: [0:52] Yeah, it's been seven years as a program manager, but initially, I started off as a developer on the team for just under two years. It's a bit of a trip.
Matt: [1:06] You've seen TypeScript's growth from what was just a pretty small, kind of fairly niche library, all the way up to being what it is now, which is a titan, as I've described in the notes. What has that process been like for you?
Daniel: [1:26] It's been so much fun at every single stage. My history with TypeScript is, when it got announced, I remember seeing it from the outside and being like, "That's such a cool idea. It makes a lot of sense, but I don't think that Microsoft is going to pull that off at all."
[2:16] Again, as an outsider, if you read this thing, you were like, "Am I going to get sued for using this software?" TypeScript didn't go that journey, but it's part of that outside thing where you see this and you're like, who knows if it's good, it's even going to be around in a year?
[2:32] Because it is so early on the open source process within Microsoft had not been proven out at all. Completely different culture. Then I joined around the 1. array literally a month after it went 1., and not even remembering that it really existed by that point because it was that small.
[2:54] [laughs] I knew I wanted to work on languages and developer tools, and things like that. That was really something I wanted to push for. It was a passion of mine. The early days were incredible because there was so much that was changing. The compiler was going to get rewritten. We were moving to GitHub.
[3:15] We were doing all of these things. Because the compiler was getting rewritten, I got to get involved with all the re-implementation of the features that we hit loss from the first version of the thing, learn the underlying architecture. Then there were all these developments of, "There's a competing type checker."
[3:35] Now we got, "Where's that going to go?" "There's this thing called AtScript. Where's that going to go?" You just joined this team and there's a bunch of these...not threats exactly, like, "Is there a better thing? Are you going to be around?" That's a really tough thing to square. Over time, I think we made a lot of sound decisions.
[4:00] We tried to do right by our community, the developers, just pushing for more openness, pushing for more transparency and discussion, and things like that. That growth was amazing because you start seeing, "We're being used everywhere." You have to find ways to scale and have different priorities every two, three years, or something like that, more frequently, really.
[4:27] There's these themes every few years as well that you end up finding that you're following, too. That's a lot of fun as well.
Matt: [4:33] Interesting. You started out and you were a warring tribe among other warring tribes, trying to find your place.
Matt: [4:40] You got a sense of, "We're competing against these other libraries that are doing something similar." At some point, Angular adopted TypeScript. That was part of the journey. What were the steps that took TypeScript from that small stage into where it is now?
Daniel: [5:00] Yeah, it's so funny. I'm going to do the best that I can to recall what I remember because there are so many people who played a part in this. Remember, when I joined this team, I was a baby. You don't quite comprehend everything that's going on around you. Here's my recollection.
[5:34] Now, what we see as a need for Angular is we need this concept of annotations, this ability to mark some declaration, so that some build step can process this thing and optimize it and basically say like, "OK, that's an output. Then, if this thing is now..." Basically, if you're familiar with what Angular does today, it's like the early versions of that.
[6:01] It was inspired by a lot of like the Java annotations and C# attributes where you could mark something in it, run either at runtime or ahead of time, do something on your code.
[6:14] This was theoretical. It wasn't a real language that existed. It was like, "Hey, what if you had a language that did X and Y and Z?" Luckily, we had...JT was our PM at the time. They've worked on a bunch of other things. I think they're involved more in the Rust community right now and more stuff, of course.
[6:39] They made the sound decision of saying like, "Hey, why is there this extra effort? Is there an ability for us to reach out, discuss, understand the potential for collaboration?
[6:50] We met with the Angular team. We found, "Hey, I don't know if the thing, there was like, "Oh, they're not evil." We were a perfectly friendly team, and they were a ton of fun to hang out with and just bring that bond together was phenomenal.
[7:09] There was this clear picture of, "OK, well, what are the things that we would need to do for TypeScript, so that we would be able to power Angular?" Angular doesn't need to create its own language. I think most of the team didn't want to create its own language.
[7:22] In fact, there's this thing I often joke around is Rosenwasser's law. It's like every team that has the chance to make a language will, and you have to pick your battles in that space, because it's not a small investment. It is a long-term thing.
[7:41] We said, "What are the things that you find are missing?" It's like, "OK, of course, ES6 support was a big thing back then." The team was pushing hard on trying to implement all of the ES6 features that we had not already implemented because we had already implemented some things early, and then it was also decorators, which was...It was annotations.
[8:08] Again, this is, I'm pretty sure, JT, collaborated with the Yehuda Katz and also the Angular team to try to understand like what are the sorts of things?
[8:17] I think the core idea was if you do decorators, any other tool can see decorators as annotations. Decorators being a runtime thing, annotations being a build time thing. Then, you can always layer the build time thing on top of the runtime thing. That was the approach we took.
[8:35] Then the last thing I believe was editor support that didn't only work on Windows because it's like, "Sure, you have all this cool tooling. It only works in Visual Studio. There's a few people who have been able to make it work in..." NetBeans, I think, was one of them, and Eclipse, but not really anything else. It's like, "OK, well, that's how TS server."
[9:03] If you're familiar with that, got it and start, because you needed to have support for these smaller editors that didn't have a fully-fledged project system and all that stuff. TS server got its start because we were like, "How do we power this for Sublime, for example?" That was the big one.
[9:19] We also built a Sublime plugin, too, for TypeScript. That's a lot of things. I got probably went in deeper than maybe you wanted.
Daniel: [10:26] Let me answer that first. There's a term called the dark matter developers. It refers to the developers who are doing stuff. They don't tend to show up on surveys. They don't tend to show up in a lot of aggregation.
[10:45] They're typically working in tools that you don't hear about often. You see stuff like Stack Overflow and State of JS, where they show that TypeScript is one of the most loved languages, one of the most used and wanted languages.
[11:29] I'm not saying that it makes sense in every context. Sorry about the ambulance in the background. Clearly, if you are starting a new project today and you intend for it to be around for a while, it makes the most sense to get some type checking.
[12:02] It is becoming the default for long-standing development and stuff where you think that you really want to rely on good tooling and great checks and stuff like that.
[12:15] The way that we got there is there was this lead-up to the NG-Conf, the Angular Conference of 2015, where the team wanted to announce on stage, TypeScript is going to be...I don't know if at that point, they said the default or the only option. [laughs] They basically said, "A-script's not a thing, TypeScript is, and TypeScript is implemented decorators."
[12:43] Once you see that happen, Ryan on my team has pointed out, you can see the search history of TypeScript and it starts to pick up on Google trends of like, "Oh, yeah. Everyone's starting to search TypeScript now." It's phenomenal.
[12:59] That's where we first got our pickup because there was this massive Angular community and being able to support them was this massive...It's an approval in TypeScript, say from Angular community. Because Google supports Angular, it was Google saying, "We trust this team at Microsoft to work on this thing."
Matt: [13:50] We're in the post-MG-Conf 2015 era, basically, is what you're saying. That was the moment that it suddenly kicked off.
Daniel: [13:58] Yeah, I think so. Right after that, it started to kick off, and we saw so many more issues being filed, all that stuff. We were also very cognizant of the fact that TypeScript had to be able to support many different stacks, many different approaches, many different libraries.
[14:23] There was this weird place that we were at where we were starting to see prescriptive stacks forming where it was like, "Oh, if you're using Angular, you're going to use TypeScript as your compiler. If you're using React, let's say, maybe you're using Babel as your compiler and you're using Flow as your type checker." That was a place where we were starting to get a little bit weird.
[14:49] Not weird, but we were starting to see this unnecessary schism. We didn't want this perception to start getting widespread because we had seen the need for JSX. We implemented JSX at some point because there was this thing in the community where people were saying like, "I love JSX, I love TypeScript, but I can't get them to work together."
[15:13] People were doing these hacks to try to transform TypeScript or there was a fork of TypeScript that supported JSX. We supported it. That was on Ryan. He saw the need for that, but we were starting to see people are getting the sense of like, "Oh, maybe there's a Facebook stack almost, like you've got to use these things."
[15:36] We very much wanted to avoid this place where TypeScript was seen as only used in one framework, one library. We started talking to a lot of people. We started trying to understand, like, "What's stopping you from using TypeScript today? Is there a perception thing?
[15:56] Is there an issue with fitting it into your build, stuff like that, because we had started hearing this stuff like, "Oh, I would use TypeScript, but I use Babel for my build, and I don't want to figure out how to do this stuff." There were reasons why it made sense to pick one stack versus the other. It makes sense when you have this separation of concerns.
[16:19] To Flow's credit, they decided to focus solely on the type language, and they allowed compilation to occur with a different tool. That actually fit in a lot with a lot of people's build tools better. There was this pitch like things were different. TypeScript is this whole thing. You have to buy into the toolset.
[17:11] 2016, I get asked if I want to become the PM on the team. I'm like, "I don't know." I'm torn. I love development. I love programming. For three weeks, I cannot give my potential manager the answer. It's a whole thing. I go to NG-Conf because they say, "Well, we need someone to talk at NG-Conf, anyway." I go there and I announce.
Daniel: [17:41] I'm having such a good time. I'm like, "Yeah, I could get used to this." I say like, "I'm going to be the PM." [laughs]
Matt: [17:47] Wow. They basically push you out on stage and say, "This is the new PM," essentially.
Daniel: [17:54] I could have said engineer at that time and I decided not to.
Daniel: [18:00] That was the official time when I decided to switch there. After that, there was a bunch of questions. One was, can we add support for Babbel? Should we add support for Babbel? Does it make sense?
[18:17] This was an instance where I feel like maybe there was like this getting off on the wrong foot. Apparently, there were earlier conversations. It was like, "Oh, it doesn't make sense. Maybe it does make sense."
[18:29] I don't know what exactly happened. Maybe it was a conversation about whether the internals at Babbel and TypeScript could be shared in some way? I wasn't present for that. We did a lot of this discussion with different users who were specifically not using Typescript.
[18:45] This was the key thing is a lot of the time people end up talking to their users to understand why are you using this thing? Why are you not using this thing, whatever? What made you decide to use this something? The key thing is you're trying to understand why people are not picking the thing that you are working on.
[19:05] I'd be going to different conferences trying to ask people like, "What's swaying you in one direction or another?" We've gone to different companies to talk to people. At Netflix, we had people on two different type checkers within different teams. We're asking like, "What made you decide to use it? What made you decide not to?"
[19:23] A big theme that we got the sense of was if you could put TypeScript in a Babel build, that would be phenomenal. It took a lot of internal pushing for this. Eventually, we got buy-off to say it makes sense.
[19:43] We had one of our engineers help contribute TypeScript support to Babel, which was massive at the time. [laughs] Because you're also sort of trusting that other people are going to...You're going to be able to hold the same quality bar. You're going to be able to have a coherent message about how you do development with this language.
[20:06] Languages usually have a toolset that does all of it, type checking, transformation, all of that stuff. This is the first time where we started to let go of that. Once you enabled Babel, every build that says use Babel in this place, can now support TypeScript easily.
[20:27] Now you can use TypeScript in your React Native Bill because Babel supports TypeScript. This was a massive thing that unlocked us from so many stacks. It really started to make us feel like you could use it regardless of your library choice. It's funny because that was the tooling.
[20:52] There was another aspect of it which is actually the type system. When I switched to being a PM, I started chatting a little bit with Yehuda Katz again, or for the first time. This was, "Hey, it's been a while."
[21:12] I was trying to understand what is the support vector for something like Ember. Ember had decided to rewrite its core in TypeScript. The user story for Ember didn't make sense yet. You couldn't use TypeScript with Ember if you were deciding to use it as a library.
[21:33] The reason for that is because Ember has taken backwards compatibility very seriously. It predates a lot of the things that TypeScript worked well with. We started off, you can do classes, sure. You can do interfaces. All the stuff that you assume that you're going to get from a typed language that's object-oriented based on Java and C# and C++, and all of these other languages.
[21:59] Then we added union types and all this other stuff. I think one of the last few features I worked on before I switched to being a PM was string literal types. There was this question of how could TypeScript support Ember and similar libraries. The way that it worked was that Ember has these Get and Set functions to support reactivity.
[22:26] Every time you want to set a property, you have to go through a reactive property. You have to go through a Get every time you want to, or...You know what I mean? When you're reading, you Get, when you write, you Set. It seemed like, "We have this notion of literal types now. Is there something that we can do there?"
[22:54] I thought pretty hard about this. I remember being at dinner and this was a dinner on my own. I'm not with a notepad across the table, "Hold on, I got something I got to write down." I was just thinking about it and sketching it out. I was, "It would make sense if you could query the sorts of keys that you have on an object."
[23:18] Then you need some way to grab that thing out afterwards. I played with this idea until I brought it back, and I spoke with another engineer on our team, Wesley. Was he an intern at that point, or was he just joined the team? We were able to whiteboard this for a little bit, and we were talking about it. He was like, "Oh, does it make sense for it to be a new kind of constraint?"
[23:43] You could take a T, and then you could say, "I have a something that doesn't extend something else, but it's like K keyof T," or something like that. It was like, "Oh, it's almost there, but it really should be its own sort of type." That was the origin of keysof at the time.
[24:04] That became a prototype and keysof...Andrew's reimplemented it. He's like, "Well, if you can do this, you can do these other inferences and whatnot." He also renamed it keyof. At the time, that was contentiou,s and who cares now really?
Matt: [24:21] Everyone loves keyof.
[24:39] A fundamental operation is grabbing keysof of a thing and being able to grab properties and set them and whatnot, too. You can now support a get and a set, which is pretty basic, but it's a higher order thing that you can support in the type system. Now you can model.
[24:58] At the time view, I realized, also had some of this as well. You need to be able to infer the names of the things that view's configuration object is saying. You want to say like, "I have properties like first name, last name, and age." You write them as strings when you're declaring the props for you, or at least you did back for view to his original API.
[25:18] I don't remember exact things now. It's still similar, but you can create, take these strings, and now you can say I need to be able to map on that in some way. It felt dangerously close. We weren't quite there.
[25:33] That was around the types or type two/one timeframe. And then at the close to the end of the release cycle, like the beta, we had done keyof. We had done indexed access, which is the way that you say like, "I have a key. Now, get me the thing."
[25:53] For a couple of days starts showing this like a little syntax off, where it's like, "What if you could iterate over each of the properties that you had and create a new object?" I'm like, "Oh, it's Python's comprehension syntax, where you can say for every element of this list, map it in some way."
[26:17] We iterated on that for a little bit. He comes in with an implementation, and we're struggling like, "Do we shift this? It's so late, but it's so clearly useful." It was like, "Don't you want to innovate here? Don't you really want to wow people?" I'm like, "Absolutely. I want to wow people here."
[26:41] All of those features, keyof, indexed access types, and mapped object types is what that was called. All went into that release. It helped us almost support view, helped us support a lot of Ember and helped us support even backbone, which was...I don't think really getting used by this point, but you still have a lot of this coding.
[27:09] At the time, that was like there was interest in moving to TypeScript. At the time, I was talking to LinkedIn, and they were like, "We're a backbone stack, and we need to move all of our code to React and TypeScript.
[27:22] I don't know if I'm...Wait, sorry. Was that LinkedIn or was that...? No, no, no, I'm sorry. I'm sorry. I'm sorry. That was...I'm confused in other internal code things at Microsoft, so it was not...I apologize. That's...
Matt: [27:41] Can we see you saying we need to take our old code and turn it into TypeScript? I would love to talk more about that...
Daniel: [27:48] Sorry.
Matt: [27:48] because I find that super...No, no. That was amazing. I find that super fascinating how the motivation for creating each new addition to the type syntax or all of that stuff. In 2.1, it sounds like you had map types, you dropped index access, you dropped key of in one release. That's crazy. I didn't know that. That's amazing.
[28:14] From there then, we got conditional types in 2.8, template literal types in 4.1 further down the line. What motivates the team to keep adding stuff to the type-level syntax?
Daniel: [28:33] I would say the big ones like you just mentioned, conditional types, those were often motivated from us talking to other developers and trying to understand what their use cases were. Conditional types, I remember coming back from Microsoft's Build Conference. Their name is escaping me, but they're phenomenal. I remember talking to them online as well.
[29:05] I got to meet them in person and we had this entire conversation about... [laughs] It was Knockout, actually. We're talking about I want to be able to express patterns of what Knockout does with their observable model. With Knockout's framework, it's very similar to most observable models.
[29:28] Not like our XJS observables, but more like reactive signals, like MobX, that sort of thing. You set a thing, some other stuff gets updated automagically. Then you wrap on an array, and it becomes a reactive array. You wrap an object, it becomes a reactive object. A primitive doesn't get mapped is the whole idea.
[29:48] You need a way to say, "I'm going to wrap this thing if it satisfies some set of types." That was conditional types. Give me a way to be able to say, "If it's an array, it becomes a reactive array" of whatever you had. If it's this, it's a reactive object, and leave it alone otherwise. That was the core idea of conditionals.
[30:18] That took a little bit of iteration because we were deciding, is it a match type or do we just go with a choice of two and you can chain them with conditional types? That's where we ended up there.
[30:33] Then template literal types, similar deal. People wanted to be able to express like, "Oh, this only takes strings five characters long." We're like, "Oh, reg ex types." What if you could have a type that was a regular expression, and that just rejects any string that doesn't accept the regular expression?
[30:53] Except now you need some mechanism for being able to capture from a regular expression. That doesn't make sense. You now need weird capture syntax that extends regular expressions. I'm also extremely anti-regular expression for production programming. [laughs] I don't believe anyone gets it right. We definitely get it wrong on our team.
[31:19] I've tweeted before, like, "How do you write regular expressions?" One of the options is just I write them with bugs, and the other option is I rely on Twitter polls because no one does it right. Everyone forgets that your regular expressions need to be anchored.
[31:39] We had an implementation of regular expression types and I said, at a design meeting, like "Effectively, I'm vetoing this. There's no way I feel comfortable with us doing this." Regular expressions are highly engine dependent. [laughs] If you just say, "Oh, let the engine take care of this," then you have this entire other problem. Template string types made me way more comfortable. [laughs]
Matt: [32:07] Yeah, OK.
Daniel: [32:09] Because now you're saying, "OK, I want to support patterns, but I also want to be able to infer from parts of the pattern. I want to be able to say it starts with this string, ends with that string, and then in the middle, I want to grab whatever's in there." It composes really well with the rest of the type system.
[32:27] You are creating a new language of pattern matching, but at least you don't have to worry about some of the edge cases of regular expressions or patterns binding more tightly than anchors at the very end and the beginning of [inaudible] .
[32:43] People would not write these correctly. One of my favorite things is that we said no to that. A rare occasion where we were just like...The team was so tempted and were like, "It would be so easy." No.
Matt: [33:01] The veto came down. Wow. The idea then is that you had these template literal types and they could compose with conditional types that you already had, so you could use the infer syntax to just do capturing with them.
Daniel: [33:14] Exactly. Admittedly, this stuff gets hard to read in some cases, but the whole idea is you look at what you have in your language primitives and you look at what people are really trying to accomplish. A lot of the time people say, "Ah, I just need a regular expression, or I just need to do this." Conditional types allow you to capture types out of other types.
[33:40] Now you can capture types out of string literal types to say when you give me this string, try to match around it, the same way that you do with other types, and then just give me whatever's inside of there in some way. People are building amazing things with it. I still see. [laughs]
[34:02] This is me just saying don't overuse it, but it is amazing to say like, "Oh, I can define a router and I can parse out the route to know exactly what properties I've expected to come back." The type system just keeps up and the tooling just keeps up.
[34:17] The auto-completion just works, which is not the case for a lot of languages that are like, "Oh, I'll give you a macro system. Oh, we'll give you templates in C++," and then the language service often cannot keep up with that sort of thing. It's impressive how far we've gotten with that. [laughs]
Matt: [34:38] If we talk about the different areas then, we've got Angular adoption. Then you start introducing these different type-level concepts into the language to support different frameworks, basically, to reach out to more communities, so you can say, "TypeScript now supports Knockout, Backbone, Ember, React, and supports Babel as well."
[34:58] Then I guess you end up in an era where TypeScript is now being priority supported by new bundlers. It's build and it has to be C right now, looking to support you instead of you supporting them. That's where we are now. This is the era that we're in.
Daniel: [35:16] Yeah, it's really astounding. The idea that bundlers said TypeScript by default was like a phenomenal change because a lot of people saw it as this burden of like, "Oh, we have to support TypeScript now." Again, the sentiment was who knows if this will be around in a few years. There was an early skepticism.
[35:38] I remember going to Node conferences and hearing a conversation at the side of a table. People were like, "Everyone's talking about TypeScript. What if it's the next CoffeeScript?" I said, "I hope not because then my team would be out." Then the person was just like, "Oh my God, I'm mortified. This person's been right next to me."
[36:35] For us, it's like, "Wow, not a lot of people would put that sort of trust in a new runtime." Again, it's not a bundler where you can swap it out. It's a runtime. This is a thing we're like moving target. New syntax gets supported. Syntax bug needs to be patched, something like that.
[36:52] Where we can move a little bit more quickly than an engine team where, if you ship syntax that's not supposed to work and then a bunch of JS developers rely on it, then if you stop supporting that, it's not the JS developers who get impacted. It's end users.
[37:09] Runtimes are a little bit more sensitive to that sort of thing. It's easier with a server-side runtime, but it's a big step of trust. Clearly, ESBuild, and SWC, and all these other tools trust that TypeScript has longevity and is worth supporting, so that's amazing.
Matt: [37:30] It's kept me in a job as well, which is quite useful. Thank you for that.
Daniel: [37:35] This is the thing, you believe a lot in what TypeScript can provide, the benefits. I think you've mentioned a lot. You, you get it right. You understand it. There's checks, it's an amazing thing for checking, but the tooling that it provides is also one of the fundamentals.
[38:18] It's a goldmine to have a type system that you can consult for the next step of what you want to code. It's not just checking. It's not just navigation. It's also suggestion. Proactive programming that makes you feel confident because it's aided by a type system.
[38:36] I think that gives you so much of a productivity improvement. Often, we've explained it in terms of, "We feel that this is useful." It's like vibes.
Daniel: [38:52] Everyone's, "I've used it. It's great." Airbnb had this report years ago where they found some percentage of bugs could have been just caught from a type checker earlier on. Microsoft Research found that there's a study where between both Flow and TypeScripts, using a type checker caught 15 percent of bugs for them as well.
[39:27] It catches stuff early. It makes you feel more confident. It makes you feel like you can explore code, especially if you're a new user. If you're a person who is coming to a dynamically-type code base just out of college or something like that, and you're, "This product already exists." You might go learn, let's say you use Python, "I got to learn Django to learn this. I got to do this."
[39:52] The project structures may be regular, but you don't still know where certain things exist, where it's defined, how to find these things. A type system allows you to get through that regardless of how the language works in a lot of cases, too. That's pretty amazing. I've always been a believer in types. [laughs]
Matt: [40:13] I would talk to [inaudible] for this as well. He said, "That's something that I didn't quite really understand about the TypeScript team is that you're focused on tooling over types," I think is the right way to...maybe not over types, but types-enabled tooling.
Daniel: [40:30] Yeah, because I would still say as much as the underlying message is there for types, power the tooling. That's where it carries because you can also power the tooling of...I don't know if I mentioned this already.
Matt: [41:38] Go for it.
Daniel: [41:39] It's so crappy. That's a tame one. It's so crappy, the way people write it, because it's so poorly specified. No one's really writing JSDoc. Again, it's like vibes. Like, "Oh, I think that I'm writing the right thing. Yeah, object. That's a type. String. Cool. Now we're cooking with fire." It was just so bad. I was skeptical that we could get very far.
[42:09] Once you start seeing it in action, you're like, "Oh." This is where my thing is. I love to push the buttons on the product and say, "But I keep screwing this up. Let's fix that. I keep screwing that up. Let's fix that. Everyone does this. Let's try to gracefully recover." This is where the beauty...I love this as well.
[42:34] When I got to first work as an engineer on the language service, you realize that there's an art to it because you're programming for someone, not necessarily yourself, but you can empathize so much. You say, "Oh, when I hit a dot here, it's parsed incorrectly, but I know what it should work." Reinterpret this and try to come up with the APIs to make it work.
[43:00] With JSDoc, it's like, "Oh, well, the order is this in the spec." "OK, but I never write it like that and I'm sure no one else writes it like that." We joke around that I could do a comedy skit in a design meeting on how to screw up JSDoc constantly. I was like, "We got to gracefully support this and that." It's not perfect, but we could get very far with that.
[43:30] Going back to what you've mentioned before, even though we know these things, we know that the tooling is what draws people in because it's like, "Oh, my God, the auto completion, I could never live without that." You go to language without that now. I have thoughts on that, by the way.
[43:49] You go to language without that now and it's like, "Oh, this is so much harder." Even still, the team, it has still a little bit of a bias towards focusing on the type system and the core compiler. That's OK because at the end of the day, that's the core thing that powers everything else. If you have a bug in your type checker, that typically means you have a bug in the language service, too.
[44:18] When it becomes clear that we have an issue with language service, the language service being the thing that powers the editor tooling, we're very perceptive to that and we want to push things forward. We see the value of like, "Oh, what if we could get TypeScript to respond faster, even though it's not fully loaded? You could still respond to partial requests.
[44:43] What if we could get it running in the browser? What if we could get it running in these contexts, snippet completions, better auto imports, improving the quality of reliability of the language service?" Those sorts of things are some of the things that are top of mind that we've been working on on that side of things. It's really fun.
Matt: [45:04] Interesting. Really focused on tooling and really focused on the developer experience of the whole thing. That's really what TypeScript is famed for. I'd love to roll the clock back now. We've now gone from day zero all the way to day whatever we're on now, thousands and thousands.
[45:22] Enums in TypeScript are a really interesting topic, because it says quite a lot about how TypeScript has evolved as a language and how the team has made decisions about TypeScript, because I've had interviews with Anders and stuff, and I think there was a conference where all four of you were chatting together, so you, Ryan, Anders, and someone else.
[45:48] The quote was, "If TypeScript enums were proposed today, I'm not sure they would make it into the language." What does that mean in terms of the way that TypeScript has developed, and what has changed about the way that you see TypeScript?
[46:35] It was unclear, even if TypeScript added these features, was ECMAScript 6 going to come out? Because it had failed to deliver ECMAScript 4, which was the last time there was this big effort to add a lot of new features to the language.
[47:47] Erasable also often means erasable in a way that a naive compiler could transform. It doesn't need any type information to do that transformation. Something like Babel only operates in single file at a time, doesn't have full type system understanding of what's happening. It doesn't know how to do some transformations across files. Stuff that. Namespaces violated that.
[48:18] Namespaces can't be reliably transformed in a way that they're supposed to merge across files. It can be transformed within a file. That's OK. That we've seen as the mistake, but it seems like it was going to make it into the standards.
[49:00] We have reps from Flow and from TypeScript saying, "This would be really useful." Other people within the committee were saying, "You could just use an object for this." I think the real sin was const enums in a sense because these are enums that require type system knowledge, cross-file compilation, stuff like that.
[49:20] They are not preserved in your source by default, which means that they can't do the naive transformation. The good part is this is sort of the misstep. This is why it's a necessary evil. It increased our compilation speed dramatically because every reference to an enum as a const enum can just be inlined, which makes a numeric check against the kind for every node much faster.
[49:51] TypeScript users benefit dramatically from this, even if they shouldn't generally use const enums. I find the current place to be just unfortunate. I wish enums could make it into the language. Maybe they can.
[50:08] My current thinking with Ron on our team is, along with Ron Buckton's pattern matching proposal, maybe there's some mechanism for tagging with enums or something that where it can work a little bit what Scala has, if anyone is familiar with that, with applications and unapplications of a type. It's a whole thing. It's very cool.
[50:35] There might be room there in the future. I don't think that there are this massive misstep. I wouldn't feel bad using it in code today. Then anytime I've tried not using enums because it feels bad, I've regretted it, to be completely honest with you.
Daniel: [51:27] That was a whole thing with...Decorators, when we added them for Angular and other frameworks, they were put under this flag called experimental decorators. The proposal kept evolving over the years. There was a new decoration proposal. "Oh, here's a decorators proposal that's actually more macros than anything else, but they only work on classes."
[51:51] We pushed against that one. I had a lot of technical reasons on that. Where we are now I feel is pretty good. Decorators in 5. will just be available by default. They don't need to have a flag.
[52:13] They don't use the old semantics, but the cool thing is there was a slight divergence with where the proposal was going and where TypeScript was, where does the decorator go before or after the export keyword? We recently went to TC39 and made the case that, "Hey, it's been eight years that this has had this syntax and nobody has complained about it."
[52:39] Clearly, there's some evidence here that people enjoy this and prefer this. Every library author we've spoken to prefers this. We should just go with that, and we were able to get headway on that.
[53:10] That's one place I think we made the right decision and we did not try to implement several different intermediate versions of that proposal, even if they were standards-bound. Standards can change until they're standardized.
[53:26] Even late standards get changed sometimes because you realize, "We did it wrong." We've been trying to stay close on that.
Matt: [53:35] That makes sense. We're nearly up to time. I'm going to ask you one more question. This question is the question that I always get asked. It's in every YouTube comment in every video no matter whether it's about that or not. I'll just ask, types or interfaces?
Daniel: [53:56] Interfaces. I have a tweet that was a one-off from a while back. Every month or so, I get another two likes or something on it. Apparently, people keep referring back to it. I'll try to give some context. I think whenever you have this choice of A or B in a language, the answer's usually it depends.
[54:21] We're all looking for a quick and easy answer. My quick and easy answer is interfaces, but I'll explain why. An interface is only really used to describe object types. It's used to extend object types so adding properties or specializing properties or things like that.
[54:44] The cool part about interfaces is that they make sure that you're actually creating subtypes roughly. You're actually saying, "When I override this property, it's still compatible with the one that I'm getting from the other one.
[54:57] When I am adding a property, it's still compatible across all of the things that I'm extending." You can extend multiple things. If they conflict, it will tell you that you need to pick one or specialize. For object types, interfaces make the most sense.
[55:19] When there are cases where you need to omit a property, you can extend from the helper-type omits of whatever the original type is with the properties you want to drop. Now, there are other specific things with type like you can't have an interface of unions. That's why I tend to prefer interface.
[55:48] If you have a case where you need an intersection, if you don't know the type that you're intersecting ahead of time, that's when you need a type alias. Prefer that, but at the end of the day, it might not matter. It might just be your personal preference. If you're extending, I would always say try to go with interfaces, even though "interface" is a wonder word, sorry.
Matt: [56:16] That's what people always say as well. That's their follow-up. "It's not interface script. It's TypeScript."
Daniel: [56:21] Yeah, exactly. I get it.
Matt: [56:26] Let's finish there. That was fantastic. I feel like we got a whole scope of TypeScript history and how it's got to where we are. Thank you so much for joining me. It has been a pleasure to talk to you.
Daniel: [56:38] Thanks for having me. It's been a pleasure.
Matt: [56:40] No worries.