Video details

Gil Tayar @ ReactNext 22 - Typed JavaScript? For real?

JavaScript
08.03.2022
English

ReactNext 2022 www.react-next.com Israel's Annual React & React-Native conference
Powered by EventHandler ----------------------------------------- Typed JavaScript? For real? The “types as comments” proposal and what it’s all about: A major earthquake has hit TC39, the JavaScript standards committee. A proposal for adding types to JavaScript has just landed in the committee, and has been approved for Stage 1. What is this proposal all about? How did it come to be? What is the motivation behind it? What are its pros and cons? Why are some people excited about it, some wary, some angry, and some afraid? As one of the writers of this proposal, I will delve into the details of the proposal, and try to answer all the questions above.
----------------------------------------- Gil Tayar: 35 years of experience have not dulled the fascination Gil Tayar has with software development. His passion is distributed systems and figuring out how to scale development to big teams. Extreme modularity and testing are the main tools in his toolbelt, using them to combat the code spaghetti monster at companies like Wix, Applitools, and at his current job as software architect at Roundforest.
In his private life, he is a dad to two lovely kids (and a cat), an avid reader of Science Fiction, (he counts Samuel Delany, Robert Silverberg, and Robert Heinlein as favorites) and a passionate film buff. (Stanley Kubrick, Lars Von Trier, David Cronenberg, anybody?)
Unfortunately for him, he hasn’t answered the big question of his life—what’s better, static or dynamic languages? But he’s working on it.
----------------------------------------- #javascript #reactjs #programming #software #development #softwaredevelopment

Transcript

First of all, movie buff who knows the reference. Come on. I love the smell of NPM in the morning. Oh, God. You're so young. Look it up. Okay. What are the three biggest trends in JavaScript in the last ten years? That's my opinion. Modern UI frameworks react view, angular, stuff like that. JavaScript tooling. I hate JavaScript tooling, but we need it. Transpires bundlers, linters minifiers. Right? And the most important one for this talk is TypeScript. TypeScript has been conquering the UI world, the front end world. And this talk is about a formal proposal. A formal proposal for enhancing JavaScript that forever will change how we view number three, impact number two significantly, and will probably do a lot for number one. This is a proposal for TC 39 that would change JavaScript development forever. A proposal for adding types to JavaScript. Right. Okay. Hi, I'm Gilsey R. I'm old all the way back to the know what ms. Dos is like ned before me. I'm an individual computer. I love it. But at this age I can't say I'm a software developer, so I say I'm a software architect. I am currently an architect at Round Forest. Obviously, we are hiring. I am also a member of the group that is writing this proposal. This is a dream for me. I mean, I always wanted less tooling. I always wanted to remove transpilers. And suddenly becoming a part of the group that is trying to remove at least TypeScript transpiling is for me a dream come true. Joining people like Daniel Olsen Vossel from Microsoft, little Dan and Rob Palmer. These are giants. TC 39. And joining them and writing and co authoring. This proposal was for me a dream come true. And as I said, I was the original author, with guidance from Little Dan. The opinions are absolutely mine. They are not necessarily of all the members of the proposal. A lot of members, we have different opinions on some stuff. These opinions are mine, so please take them with a grain of salt. They're definitely not my employers. And I was asked by the TypeScript team to add the last one. I do not speak on behalf of the TypeScript team. Okay. Also, the proposal is officially part of TC 39, which is the JavaScript Standardization Committee. It will get heavily shaped by the whole process, so it will probably not look like what I'm showing. It will probably heavily change. So no guarantees here. And this talk will be about the proposal. Where was it proposed, what is it and why? And the important thing is why I get what Kimchi Dot was talking about. The where TC 39? What is TC 39? Where it was proposed? TC 39 is a committee for the standardization of general purpose cross platform vendor neutral programming language actscript. And why is it not called JavaScript? It's tanked to a company called Oracle. And then before that, Son, who holds trademark for JavaScript but equalscript JavaScript same. Basically, all the new features you get in JavaScript are standardized by TC 39. The process is very transparent. They have meeting notes, everything really amazing. I'm probably one of the few that reads meeting notes religiously, but if you want to this is the GitHub repo. Each year comes a new version of JavaScript. JavaScript echoes script 2022 just came out, by the way, and it gives things like add and includes an async await and top level awaits and things like that. That is what TC 39 standardized. And it's a process. It goes through stages. So Stage zero is where I want to propose this to TC 39. We just write the spec, or we just write a proposal. Stage One is where they meet. They meet every two months, I think, and discuss the proposal. And if they say interesting, then it gets to Stage One. Stage one is just interesting. They're not obliged to accept it. Stage two, we start writing the spec, like, really into the details. And if they accept it, then it's at Stage Two, where they say, okay, this is good, this looks interesting. Let's iron out stuff. Stage Three is waiting for implementation. All the little details have been ironed out, and now at least two runtime. Two JavaScript sometimes have to implement it. Usually chrome v eight and others safari and firefox they all have JavaScript contents. They implemented. At least two need to be implemented, and if everything is fine, it gets to Stage four. Sometimes things roll back. I think the most interesting was annotations, like at something it was at stage three, went back to Stage two, went back to Stage one, goes blah, blah, blah. It's doing a journey. Okay, that's TC 39, and that's where we are at. What is the proposal? The Type sanitation proposal was proposed on March, march 31. That's basically April, and obviously it wasn't proposed on April 1 because people would have thought it was a joke. Really, it's immense. And it was accepted incredibly, and it's accepted to Stage One. So the committee expected to devote time to examining the problem space. Okay, so it's acceptance of the problem space, not specifically the solution. Okay, let's talk about the proposal. Let's give a brief draft and then we'll go into the details later. But let's see what it is. This is JavaScript code. Everybody knows add AEB, return A plus B. Very simple function. And this is the same code with type annotations. This is what the proposal says. This proposal says that this code will run in JavaScript without any transportation whatsoever. This is the type annotations. Everybody knows what the syntax is, right? What is it? Type. There we go. Will this pass? Okay, there's add to. So it should be added into places. So I'm passing a string and I'm passing a boolean, and it's supposed to be accepting numbers. Will this pass? Yes, it does not. Type annotations will be ignored by JavaScript. They will not be processed from the JavaScript runtimes point of view. Those are comments. The original proposal, by the way, was called types as comments. That was the original proposal. Let's give types, but have the JavaScript runtime treat them as types. We'll talk about the while later, but just accept it as it is. Thus these are also legal annotations type annotations. Is this TypeScript? No, but from the JavaScript runtime point of view this is fine. Okay? The TypeScript annotations here are fine. From that point of view, the JavaScript runtime will ignore it. Obviously TypeScript will say, well, there's an error here, and Flow and other type systems will say there's an error here, but from JavaScript point of view it's fine. So basically what we're doing is we're carving out a space in the JavaScript syntax where we're saying this part just ignore it. It's for types, just totally ignore it. You don't care what's in there. More type annotation spaces we've seen like parameters and the type annotations on parameters more are things happening after the type type something equals JavaScript will ignore it. That's about it. So we're basically defining a type annotation syntax based the JavaScript runtime will ignore, interestingly enough. Well, obviously it by chance corresponds to the same areas that TypeScript and Flow have for their type systems. So basically 90%, 95% of TypeScript programs will run in JavaScript. Assuming this proposal is accepted. I will stop saying assuming if this proposal is accepted, okay, it may not ever be accepted, but let's assume for this talk that it is. So if this proposal is accepted, then TypeScript programs, most of them, and we'll talk about the exceptions later, will just run without any transportation. And obviously we didn't choose those type syntax annotation spaces by chance. They were chosen because we looked at TypeScript, we looked at Flow and we looked at Hegel, which is another type system, and chose them according to those three and probably others. But this is not TypeScript, this is legal JavaScript. If this proposal is accepted. Okay, fine by JavaScript. Not fine by TypeScript, not fine by Flow, but fine by JavaScript. Wait, you're asking yourself why add type annotations if they are ignored? I mean, what's the point? And the answer is this is react. I dehydrate a lot because TypeScript and Flow third party type triggers like TypeScript and Flow will not ignore them. They will read the code and based on that, show errors. Okay, so we still have TypeScript showing the errors and having the errors, but JavaScript one time will ignore them. Okay, so the proposal, the summary, like first draft, we'll talk about the details later is the proposal reserves a syntax space for type annotations which are ignored by JavaScript, which are ignored by the type runtime, but are assumed to be checked by TypeScript, flow and other type systems. And by chance, not really by chance, correspond to the same places in TypeScript and flow that they already have for type annotations. Okay? We announced the proposal on March 9 before we submitted it and the Internet exploded. I mean, I've never seen a proposal for TC 39 get this much recognition and lots of finely and yes and all that. Obviously, this being the Internet, there was a lot of criticism. Most of it okay, good criticism. Not things we didn't think about, obviously, but good criticism. And some of it was like really ugly because Internet. But I will be talking about the criticism here. A lot of this will be talking about the why and answering those critics. Which brings us to the why. Why add types at all? This is not a trivial feature. I mean, adding type annotations syntax space for JavaScript is not trivial. It's not at or includes for string, right? It's not simple. So for a feature of this size, the benefit to all of us has to be substantial. And I give two graphs as an answer. This is beautiful. This was given after we proposed. Somebody sent me this. Look at that. This is pull requests in GitHub, March 2022. All of them by grouped by language. Obviously JavaScript and TypeScript are like most of them because we rule. No, seriously. But most of us are there. And look at this. If we look at JavaScript and type script as JavaScript, and I tend to look at it this way, then almost half of the PRS of the pull requests that we all are creating and open source and other projects are TypeScript today. That's amazing. Not JavaScript TypeScript. The JavaScript community and this is like Proof is using TypeScript heavily for its code. This is not like some idea of mine or an opinion. This is based on data and facts. Type allocations are used in the field and have probably proven their value. If they haven't proven value, we wouldn't be using it. State of JavaScript 2020 what do you feel is currently missing from JavaScript? Static typing is like by far the biggest. It gets less than 2021. Don't know what why, but it's still number one. So people want static typing. A large part of the community wants static typing. So is it worth the complexity? Well, yeah, if almost half of the PRS are using type annotations, then I say yes, it's worth it. Three more reasons not to add types to JavaScript types are difficult for beginners, types increase the payload and web apps. And I don't like types. Types are shite. Types are difficult for beginners to grab. It's a valid criticism if you start from JavaScript. Adding and making beginners understand types is actually difficult. But if you start from type annotations, type script or flow, then explain. I mean, my daughter, she's 15 years old. She is, God forbid, learning Java as her first language. I am so sorry for that. I have failed as a father. But she gets it. Believe it or not. She understands type, so it's not that bad. And somebody wrote on Twitter, sorry. In one of the GitHub issues, someone learning to program for the first time in the first place and long hours trying to install the various tools required. So if transportation is needed, some of those tools will go away. And new programmers searching, for example, code. Today new programmers are likely to find TypeScript code and they copy paste it into the console. And does it work? No, but if this proposal accepts it, it will. In other words, we want it or not. Type scripts are part of it and we need to get beginners to understand it. Types increase payload in apps. I don't get that. Okay, so does increase payload in web apps, so that's comments, comments increased payload in web apps. That's not true because we have Minifiers, right? We have minifiers to compress our code and minifiers can remove all the type annotations. Not a problem. I don't like types of ship. I know. I was there. I moved from Java to JavaScript and I thought the problem in Java was types. That's wrong. When I started using TypeScript, I thought the types are really nice, the problem is Java, but really it's not about me. But by the way, I was known as a TypeScript denier in the JavaScript Israeli community. But it's not about me. It's not about you as an individual. It's about the community. And the community wants types. You can see that in the graphs. They just want it. Okay, I've convinced you we as a community want type annotations, but we already have TypeScript. Why do we need to extend JavaScript? Why not just continue using Tooling? TypeScript is Tooling or flow is Tooling. Why not continue I have three answers philosophical, programmatical and political. Let's talk about the philosophical answer. We have forgotten. You've never known your roots in scripting and you've gotten like started from react, right? Most of you, but me and Norm won't probably remember that JavaScript was already a very simple language rooted in scripting, like Perl and Python. Okay, we have forgotten our roots in scripting code the code, press F five to refresh the page and boom, it works. We've forgotten we need so much tooling today. We have become addicted to tooling. And that saddens me very much because I like simplicity. We cannot not use it anymore. Juniors developers don't understand this tooling. They don't understand type transportation and bundlers and all that build steps. They just don't understand it. Senior developers don't understand it. I can barely understand it. Okay, so a lot of you are using tools and don't really know what's happening under the hood. It's not your fault. It's very complex. It is our fault for getting into this whole mess. But it's fine. I mean, there were good reasons for that, but we need to unremove them. We need to remove those reasons slowly. TypeScript tooling is a big part of the problem from my point of view. The other philosophical one is there's a rift in the timespace continuum, not just in the JavaScript community. We're coding in one language, TypeScript, a lot of us, but running in another language, JavaScript. I mean, no other language has that probably yes, but mostly no. There's a growing risk and there's a lot of the TypeScript yes, TypeScript no. And we need to mend that risk. We need to get back together and have the code be one language programmatic answer TypeScript is everywhere. Any tooling that we have, remix, Webpack, Es, Build, whatever, minifiers, all need to understand TypeScript because they want to deal with TypeScript natively. So these tools unfortunately need to evolve with TypeScript. Anytime TypeScript changes, they change their code. And that is bad because they don't really want to understand TypeScript, they don't want to understand TypeScript, they just want to ignore the parts of the types. And this proposal simplifies the tool trendously because they will have one way of ignoring it past, present and future. And we're done with that problem and most tools will become simplified and not need to follow TypeScript. And the political answer, this is where it gets TC 39 should be the arena for type systems. Should be arena where we talk about type systems and they're placed in JavaScript and not defer it to other places where stuff can happen. It's always a balancing act and we'll talk about that later. But TC 39 should be part of the process of defining what types are. Okay, so we want types, we got it as part of the language, but this will not enable us to standardize types in the future. A lot of people got that and got that immediately and they're very smart, which is because it is true once JavaScript ignores types that's it. TypeScript always has to be sorry, JavaScript always has to be backwards compatible. So once we ignore types and as part of JavaScript, that's it, we can't unagnore them back again because some old code old will stop working. True? Yes. But I believe that when the need arises, we will find a way. Let's put types in and then like a few years later say, okay, we want to standardize types and we want to look like this. We will find a way. TC 39 will find a way. What exactly it is, I don't know, but obviously there is and then those are wow, type one people, why stop it, ignoring them? Okay, as long as we're doing Types, let's do them all the way. Fully embrace TypeScript syntax, build a type system of our own, do runtime checking, optimize performance based on types, all good and valid criticisms. Okay, so why not fully embrace TypeScript? Let's go all the way. And this is very important. I mean, everybody is using TypeScript. It's the de facto standard, why not use it? Okay, TypeScript is developed by Microsoft. Okay, Microsoft are also part of the standardization of this proposal, by the way, and from my point of view is amazing. But TypeScript itself is developed by Microsoft. They're not done innovating. They're still creating versions with more, more and and more type stuff in it, which makes it better and better and better. Innovation will be hampered if we stop here, if we freeze here, stop. That will stop innovation. TC 39 is much, much slower at doing stuff and that just will kill the evolvement of TypeScript. If we do TypeScript, that will monopolize TypeScript, but there are other type systems out there. Flow is great, hegel and probably others, okay? If we do not standardize, we end the monopoly and let other type systems flourish. And maybe there will be other things that are better than TypeScript. TypeScript is huge standardizing. It will probably take ten years, 15 years. It will never end. So even if we wanted to, it's not something that will probably happen. Okay? So why not build a type system of our own? And there are two camps here. Let's make it simpler and let's make it cleaner. Oh TypeScript is too complicated. I have the master of this sitting here. Where are you? Dan Shapir well, TypeScript is complicated for a reason. TypeScript and Flow, they're complicated for a reason. JavaScript patterns are complex. We want this code below to show a syntax error. We pick an object and ask it for only the fields A and B to be there and then dot C. That should be an error. This is very difficult to define in a type system. That is why TypeScript is complex. A simpler type system will just not be as useful as TypeScript today. If we define it, people will not use it. They'll continue using TypeScript. Well TypeScript is too complicated. It's like a cleaner Haskell or Camel reason type systems that are really simple, they are okay, well, not Haskell, but they are mostly simple cleaner and have the whole power of TypeScript. So why not do that? And the answer is they're cleaner because they were built for cleaner languages, not for JavaScript. JavaScript is dirty. I mean, it's how much? 95? 25, 27 years? Not something that we can put a clean type system on, so why not? Okay, so that's why we can't build a type system around or use TypeScript. Why not? Well, let's go all the way. Let's do runtime checking. Why stop there? Okay, TypeScript? Well, first of all, this TypeScript do runtime checking. When you write TypeScript, does it do runtime checking? No, because when transporting, it erases the types. So today you're using TypeScript and you're not doing runtime checking, which is fine if you think about it. Haskell, Java, all typesafe languages, C plus plus mostly types A for us. They do all the types of at compile time. They don't do almost any runtime type checking. Almost. So all the languages don't do runtime type checking. Having said that TC 39 suggested maybe for parts of the proposal, doing some level of runtime checking. We're looking at it and the last one is let's optimize based on types. If I know that foo ad is getting two numbers, then I can make ad the function ad be much faster. There's a whole thread by Matthias Binans, I hope I'm saying the right. He's one of the VA developers. He knows performance, he knows JavaScript runtimes. He said this is not going to work, not going to happen. And he has a whole thread on Twitter on that. Please read it's. Very technical, very good. To summarize well, white types, they complicate the language because the community wants it. We've seen the graphs, types are good, but why not continue with TypeScript tooling? Let's stop the tooling addiction. Please mend the rift between JavaScript and TypeScript. Stop tooling being typed to TypeScript evolution and TC 39 should be part of defining what types in JavaScript are and standard. Okay, so let's do type plantations, but let's embrace TypeScript all the way now it's just too big and we need to continue evolving, build our own type system. No, because it's very complicated and if we try to make it clean, it won't work. For JavaScript, check runtime, go to Twitter thread on why it won't work. Oh, sorry. Optimize using types, go to the Twitter thread on why it won't work and check runtime. Well, no languages does run time checking. Okay, so we've dealt with the criticism, valid criticism. Let's start with the what? What exactly is the proposal? And as I said, this will undergo considerable change. This is just the first draft. I don't know what the end result is. Let's go like piece by piece where type annotation syntax faces what will be ignored by the JavaScript runtime. As we've seen functions, we have the type annotations for the variables and for the return value. But this is important because okay, justice needs to ignore the type annotation, right? How? How does it know where the type annotation ends? This is interesting, and what we've come up with is an interesting one. If you think about comments, how does the JavaScript know when our comment starts? EasyStar, right? How does it know when it ends? Easy. Star slash. Okay, comments, but what about syntax sensation space? Does it look for the comma? That's one option. But what if the type annotation itself includes commas? For example, this type annotation pair number comma number has a comma in it. So what do we do? The answer is interesting. What we thought of it may change. We look for the comma. Well, generally. But if we see braces or curly braces, or parentheses or square brackets, if we see one of those parentheses, we start counting pairs. So we balance the pairs and ignore whatever inside. So once JavaScript sees that less than it will ignore anything until the larger and obviously it will count less. Than so the parentheses will match. That is how we believe type annotations should be ignored by the JavaScript runtime and this will allow continued evolution of the type annotations without breaking JavaScript compatibility. Because anything there we can do whatever we want. TypeScript continue to evolve, flow can continue to evolve. We can have other type systems like Hegel and others that will probably flourish once this proposal if this proposal is accepted. So this will not hamper them because they just have to follow this rule. But some TypeScript and Flow type will not pass this rule. Let's ignore where. So what do we do? We change the TypeScript code and add parentheses between any type in TypeScript. I tried that. Okay, you add parentheses around it and it's valid. So some TypeScript code will need to be changed for this proposal. So we just add parenthesis. This is probably going to be a code mod or anything like Microsoft and Facebook. Meta will write a code mod that will change your code to be valid for this proposal. Okay, so we saw that variables obviously will be type annotated to define what their types are. Types type something equals something both in TypeScript and Flow and Hego. This is valid and this is the typeanotic space that will be ignored by JavaScript. Interface never like that. Why not just have types type equals but whatever. So interface the name and curly braces whatever is inside will be ignored. Class properties annotated generics obviously very important. We can't have a modern type system today without Generics. So the singing there will be supported importing and Exporting types. This is supported by TypeScript and Flow using export type and type inside will be totally ignored by JavaScript. But there are some problematic type annotations. Let's talk about them. Casting TypeScript and Flow have different casting syntaxes. TypeScript uses as type and Flow uses this parentheses in column. We need to figure it out. Except both. Except one. Whatever. We need to figure it out. Generic function is invocation this is valid TypeScript. Unfortunately it's not valid JavaScript because JavaScript thank you. It will say do something less than number, larger than whatever. Okay, so this in JavaScript will be treated as less than larger than and TypeScript knows it. They know that this is a problem. They have accepted that this is a problem and they have a suggestion like add the two column thingy over here. So they are suggesting to change TypeScript to conform to something that DC 39 can accept. And this is great, these parameters, it collides with another proposal. So this is up in the Air declarations. Theoretically they're not in TypeScript files, they're only in DPS files. But some people think that they should be in JavaScript. We don't know. Function overload we don't know what to do with those functions without bodies. How do we deal with that? We don't know. We need to think about it. Abstract Classes adding abstract before do we want runtime semantics for that? We don't know. Member modifiers that it's smack in the middle of the syntax, no curly braces, no collar, no nothing like public. What do we do? We accept these words, these keywords? We don't know. One suggestion was adding sigil. So percent public percent rate only is like everything with percent will be ignored. This will modify TypeScript and flow a little bit, but they're open to the suggestion. TypeScript subject will not be in the spec. Enums namespaces and parameter properties will not be in the spec. Why? Because those are the only features in TypeScript that don't just erase the types, they generate JavaScript, they generate code. And that is not good. Even Microsoft today has no new features in TypeScript that generate code. Okay? All of it is type erasure. So they're willing to do that. By the way, if I remember correctly a recommendation by type script stop using these definitely namespaces. I'm not using them. They will not be considered for the proposal and JSX, well, it's not part of TypeScript I really want, it part of the standard but definitely not in scope for this proposal. The consequences if this proposal lands no more transportation of TypeScript and flow with real browser ESM and we can finally remove all tooling. We'll still be checked by third party type checkers slow convergence of incompatible TypeScript flow to the new syntax tooling will become much simpler and other type systems will be experimented with. But it will take time, years until this proposal and if this proposal ends but it will be worth the wait, I think. Thank you very much.