(upbeat electronic music)  (crowd applauding)  - Alright, okay, thanks very much. 
In this talk I'm gonna talk about static type checkers  for JavaScript, specifically I'm gonna talk about  what they are, and why I think they're important.  I'm gonna talk a little bit about how you might  go about picking one to use, maybe Flow or TypeScript,  and then at the end I'm just gonna wrap up quickly  with a little bit about how static type checkers  are gonna relate to the future of JavaScript and ECMAScript.  Spoiler alert, probably not much,  but it's still a point worth examining. 
So let's start with why I think static type checkers  are important, and this is the best analogy  that I can think of, small children. 
Little kids, babies,  some of you might have them, toddlers. 
Here's the basic reality about small children,  I love my two small children very much,  but looking at it objectively the sad fact of the matter is  that small children are basically  difficult to understand to other people. 
They behave highly unpredictably,  and frankly without ongoing careful attention  they'll smell very bad. 
And the assertion that I'm gonna make here is  that all of these same properties  apply to large JavaScript projects. 
Your large JavaScript project may be  a thing of wonder and beauty to you  but the sad fact is that to everybody else  it is difficult to understand, it behaves unpredictably,  and it smells bad without very careful attention.  And speaking from experience the good thing  about small children is the situation gets better over time  but with large JavaScript projects it only gets worse.  But the good news is that Microsoft,  and Facebook, and Google have known this,  about large JavaScript projects, for a long time.  In the case of Microsoft, a while ago now,  they came up with TypeScript,  which is like a type superset of JavaScript,  which is fantastic. 
And that was actually, most notably,  picked up by Google recently for Angular too,  that was when it really came to prominence.  And Facebook also internally had this thing called Flow,  which is like a type checker that they use as well.  So let's, that's sort of an introduction to the why's,  let's get into some examples of these in action.  I think the two big benefits of type checkers  can be described as bug checking  and being able to describe your intent more clearly.  Let's start with bug checking. 
Here's kind of a canonical example,  this is a little JavaScript programme  that's squaring a number  and logging the result to the console. 
I can run this using node and it will  quite happily output the number four,  so that's all good in this case,  but let's say that I get tricky and try and pass  a string into this and run it with node,  and JavaScript, bless its little heart,  will coerce that string into sort of a number  as best it can, attempt to do  the multiplication and output not a number.  And if this was a big programme that not a number  could then propagate throughout our system  and cause chaos accordingly. 
So let's look at how we can improve  this situation using a static type checker.  We'll start with TypeScript. 
And the first thing we'll do with TypeScript  is we're gonna change our file extension from .js to .ts.  And then we're going to get our little programme here  and we're gonna add a type annotation to it here.  And to actually see this bug being detected  we're going to run the TypeScript compiler on our file  and we'll specify that we want it to output  some js later on, we'll get back that in a second.  And when we run this TypeScript compiler like this  it's immediately gonna display this error message for us.  So it's picked this up for us  at compiler time which is fantastic. 
Now if we go back to passing a number into our function  we can run TypeScript and it will pass without any problems  and then we can now run node on our output js file  that's been output to the build directory  and it will run quite happily. 
If we look at the output file  that's been produced by TypeScript  it's really just the original thing that went into it  just without the type annotations,  and this is really important to know. 
At the end of the day you're still running plain JavaScript,  all of this type checking just happens at compiler time.  Let's have a look at how we do this with Flow now.  The story with Flow is slightly different. 
The file extension stays the same, it stays as js  but at the top we're gonna add this little annotation,  or this little comment here with this special tag in it  that indicates to Flow that we want it to look at this file.  We run Flow from the command line as well,  it looks for any files with this @flow comment in it.  And immediately it's detected an error. 
And the interesting thing here is  I haven't actually got a type annotation in there yet.  So this is an example of Flow doing some  type inference for us pretty much just for free.  Can I just say if you're the sort of person  who wants to square a string you're probably  in the wrong presentation and I can't help you right now.  But flow makes some basic assumptions  about what you probably do and do not wanna do,  and in this case it's gone, "Well you're using  "a multiplier, we really should be dealing  "with numbers here."  It's then looked at the programme flow  and what's been passed in and gone,  "Well hey, you know, you're passing a string  "into this function and you really shouldn't be."  This type inference is a really really powerful feature  and in fact sometimes it can be so powerful  that our puny human brains can't really  get our heads around it. 
So to help with that sort of thing  in Flow you can also add type annotations  and that allows us to scope down the error  and track it down a little bit more closely,  and that's what we're doing here. 
So if I run Flow again it's actually  gonna give me a little bit more information  so I can track down where that error is. 
Now when it comes to actually running flow,  if I revert back to passing in a number here  there will be no errors, which is fantastic,  but of course if I try and run this it's just gonna die  'cause that type annotation is in there  and node doesn't know what to do with that.  So there's an important distinction we're making here  and that is that TypeScript is a compiler,  it takes typed script and produces js  whereas Flow is really just a checker. 
What we need to do to actually run our Flow annotated code  is we need to run it through a little babel processing step  just to strip out all of the type annotations.  And we can do that just here. 
If we output it to the build directory,  again, at the end of the day,  the annotations are stripped out,  it's just JavaScript, that's all that we're really running.  So that's the first big advantage  of using a type checker, bug detection,  but the second one is really about displaying,  or flagging your intent on what you want  your code to do and the shape of your data,  and I think this is really important. 
So on the theme of kids I'm going to go back  to another example, and in this one  we're gonna talk about jumpsuits. 
If anyone here has got kids you know they grow  at an alarming rate, so what I've got here  is a little JavaScript function  that will up-size the jumpsuit for me. 
So it will take some data structure  that describes the jumpsuit and return a new one.  All I've really done is a plus one on the size, okay?  And I can see all of you are looking  at that coat and you're going,  "What is a jumpsuit, what is this jumpsuit object?"  And you're kind of looking into it  and you've probably figured it out by now  but in you guys having to do that,  I think that's actually symptomatic of one of  the big problems with a language like JavaScript ,  and that is that sometimes in order to understand  the interface to a function  you've gotta look at the implementation. 
And that approach really doesn't scale,  and I think it's one of the big problems with JavaScript.  So fortunately things like TypeScript can help us, okay?  So we're gonna change our file from a .js to a ts again  and we're gonna introduce this interface up here,  this is a special thin that TypeScript gives us  that let's us start to describe the shape of our data.  And this is really really important. 
So having set up this definition of a data structure  we can then put in some type annotations and say,  "Hey this function takes a jumpsuit  "and it returns a jumpsuit."  And that's fantastic. 
With Flow it's a similar kind of story. 
We can just put our Flow annotation  into the top of our js file. 
In this particular case the syntax is almost identical  for how you define an interface,  and this isn't always the case with TypeScript and Flow,  but in this case it is. 
And it's pretty much all of the same deal ,  we're able to be descriptive about the inputs  and the outputs of our function without you  necessarily having to dive into the implementation.  And at the end of the day whether you use TypeScript or Flow  when you actually run this thing all of this stuff comes out  and you're just running JavaScript again. 
This is really just a compilation step,  and that's really important for people to understand.  Now I've actually just introduced  a bug on this slide, can anyone see it?  Like any good Australian web developer  I usually misspell colour at least once a day,  and that's what I've done here. 
And so this same bug detection applies  to these data structures that we pass in as well.  And to show you this in action  we'll get into a little bit of the tooling.  Here's a screenshot from Visual Studio code  which has got excellent TypeScript support,  and pretty much out of the box  it's able to look at this TypeScript file  and immediately flag that I've misspelt  colour wrong there, which is fantastic. 
TypeScript's actually super powerful  even for things like Completion,  which is probably almost unheard of in JavaScript land.  It can even show me what properties are available  in this data structure. 
And just as an aside, I've gotta say,  I do a lot of Redux work and to be able to have  this sort of, being able to describe  the shape of your data is super super useful  when describing Redux state trees. 
Because you've got a whole team and everybody needs  to have a clear understanding of the shape of your data,  and TypeScript and Flow are just  superb ways to describe that. 
And you can even navigate the data structures  using Completions and something like Visual Studio code.  The tooling support for Flow is a little bit more sparse  because Flow wasn't really designed  with this in mind from the beginning. 
A new client's probably your best bet,  this is an extension that Facebook  have built on top of Adam. 
It's a little harder to see there  but this is really the same code, Flow annotated code,  and it's still picking up that I've  misspelt colour in the file. 
That said things like refactorings and renamings,  completion, aren't supported so much with Nuclide.  So these are the two big benefits  of these static type checkers,  bug detection and describing the shape of your data.  And to be perfectly honest I think  from a code quality perspective the implications  of this are quite profound because previously  in JavaScript land we relied very heavily  on automated tests and code reviews. 
That's all we've really had in the past. 
And now we've got this third pillar that we can use  for code quality and it takes a lot of the pressure  off of our unit tests in particular, I think it's fantastic.  And I've only just shown you the very tip of the iceberg  of what these type systems are capable of. 
I think that if you are going to,  that said, I think that when you are making the decision  as to whether you use Flow or TypeScript  it's not so much about getting too much  into the details of the type systems  'cause they have their respective strengths  and weaknesses, it's actually about  the more pragmatic decisions about type definitions  and tooling. 
And that's what I'm going to talk about now.  So let's talk about type definitions first  and the importance of them and you know what are.  So I started with an example where I squared  a number but to be perfectly honest  commercially I've never really had  to write a function that squared a number. 
The sad reality is our code is never an island  we're always bringing in a whole bunch of different  external JavaScript libraries,  some potentially quite hostile or inscrutable,  and we need top deal with them. 
And our code might be beautifully typed  but how do we know that we're using  these other libraries correctly?  And type definitions help us deal with this problem.  A type definition is like a little shim  that's available for a third party JavaScript library  that defines the inputs and outputs of that library,  either using Flow type annotations  or using TypeScript style annotations. 
Type definitions are usually not written  by the original library authors themselves,  sometimes they are but not usually. 
Usually they are distributed separately from the libraries,  sometimes they can be bundled in with them  but usually it's best to just assume  they'll be available separately. 
And, at least in my experience,  availability and up-to-date type definitions  is like crucial and the big sort of,  it's gonna be the big pain point,  sticking point for how we use these things in future.  So I'll show you a slightly more practical example.  This is using React, it's just a little React component  that's spitting out a little bit of a mark up.  In this case it's just saying hello to a name  that's been passed into it. 
This is completely un-typed at the moment. 
Let's look at bringing in for starters  the React type definitions into TypeScript.  And for TypeScript the story for doing this  is really really seamless now. 
It's actually something you can just use, do use an npm,  in particular using the @types scope here. 
That brings it into your project,  puts it into your package.Json. 
And then if we go back to our Hello file  change it from .jsx to .tsx, because TypeScript  actually supports that format out of the box.  All of a sudden if we look at this in Visual Studio code  we will see that it's now saying,  "Hey, I don't know anything about this name property."  It knows what this.props is because that's a React thing  but props is really just a random bag of values  and TypeScript's gonna say, "No, I don't know what name is.  "How can we resolve this?"  So we'll basically introduce an interface again.  We'll just call it HelloProps here at the top,  we'll say it's a data structure,  it's got a name property in it that's type is string.  And then just in here we're gonna provide  a type parameter here into this generic,  when we extend on a React component. 
And all of a sudden we've been able to blend that in  and TypeScript's gonna go go, "No, hey, I know  "what this component it is now. 
"It's a component that takes HelloProps  "and sure you provided a perfectly  "legitimate prop name there."  If we misspelt that, TypeScript would complain  and we'd know we've got a bug. 
The experience with type definitions with Flow  isn't quite as seamless, it's not quite as mature.  You use a tool called Flow Typed  which as a one off you're gonna have to instal globally.  And then you just run flow typed inside your project  and flow comes with a React type definitions  sort of built into it. 
So there's no point bringing them in  but we could, for example, bring in  the Redux type definitions, and we'll do that just here.  And then once you've installed into your projects  they don't really go in package.json's  instead they get kind of dumped into a directory  and that's a directory that you're supposed  to check into your source code control system.  But once you've done that when you run Flow  it can then type check your programme  against these external definitions. 
Speaking of maturity the number of Flow type definitions  out there at the moment, about 300. 
TypeScript type definitions about 3300,  so there's quite a marked difference there  in terms of the maturity of the ecosystems.  That said I think that if you were playing  in sort of the Facebook space,  if you're working mainly with React,  I wouldn't necessarily write Flow off  purely on this basis. 
Because the type definitions for core stuff  like React, React Native, aren't too bad. 
And also there's a second factor  that I think you really need to consider  when you're deciding which of these two tools to use,  and that really is your JavaScript tool chain.  Perhaps most notably things like Webpack. 
When I, especially when I first started  looking at Webpack this is what it  looked like to me in my head. 
It can be quite intimidating and complex. 
And this picture is actually taken from  a JavaScript fatigue blog from a little while ago.  And I personally don't really buy into the whole  JavaScript fatigue thing but I've gotta be honest,  I've spent many months of my life  configuring JavaScript builds. 
And I'm anticipating I will continue to do so.  Starting with Grunt and Gulp and now Webpack.  Anyway the point I'm trying to make  is if I was to consider my current React project  that I'm working on it's a TypeScript project,  which is great, but it's a very ambitious project.  So we have a standard Webpack client build,  which is fantastic. 
We also have a server side build because we need  to server side render this too,  and okay, we can get that playing nicely with TypeScript.  It's actually also a React Native project  so we're trying to reuse, and mostly succeeding,  in getting about 80% code reuse of all of our components  into sort of an iOS app as well. 
But the Facebook React Native packaging  is a whole world and a beast unto itself. 
And then finally we're using Jest to do our unit testing.  And Jest really is running inside node  and in my experience at least,  taking this number of multiple complex build pipelines  and prizing each one apart and jamming TypeScript  into it has been a pretty gnarly experience.  And I think that it's something you should factor in  when you're making a decision, just the complexity  of your tool chain and what you're gonna have to do  to it to get the tool involved,  get a tool playing with it nicely. 
So to be clear let's just look at the two differences  between these tools and their philosophies.  Flow is a checker, it's really designed to be a bug checker.  It doesn't need to be inserted directly into your pipeline,  it can sit to the side and check your code.  Whereas TypeScript in comparison is a compiler.  At the end of the day it needs to meet Js. 
Now you can ignore TypeScript for a little while  and I've done this. 
TypeScript can omit code if there aren't any errors.  You can get away with that for a while  just to get things on their feet  or to work through more important problems,  but at the end of the day TypeScript  needs to meet code and needs to be part of your pipeline.  And I think that's a really important consideration  to keep in mind when you're using  other complex tooling like Jest or React Native.  Secondly Flow is probably, arguably,  designed from the outset to be a little bit more sound.  It's really, it's goal is really  about bug detection, from the very outset. 
It's got a very powerful type inference  and really it's called Flow for a reason,  it can analyse the flow of your programme quite closely.  TypeScript in comparison,  I think it's certainly more friendly,  but isn't necessarily quite as sound. 
To be honest for most people it probably  won't make much of a difference  but it's worth keeping in mind. 
And we've seen that the tooling support  with things like TypeScript,  with things like Visual Studio code is just superior.  That's one of the great benefits you get out of TypeScript.  So I think it also depends a lot on  the philosophy of your team. 
I work with people who are all Java developers  or Objective C developers and to them TypeScript  appeals immensely because they really like  the tooling support, they really like auto completion,  they really like a little bit of refactoring.  Whereas people who have been JavaScript developers  from the beginning and perhaps don't even know any better,  are usually just quite happy with Flow. 
'Cause they're not really used to  ever having completion anyway. 
I think Flow also probably has a little bit more  of a philosophy incrementalism about it. 
It's kind of designed to be introduced incrementally  to a project, whereas TypeScript, I think,  is a little bit more committing up front. 
And this isn't actually necessarily a judgement  one way or the other but it's worth keeping in mind.  With Flow you don't necessarily  have to have everything running  and passing at once, up front. 
But the flip side of that is sometimes with Flow  it can be a little unclear as to what's  been type checked and what's not. 
To help you deal with that there's a notion  of live coverage which is very similar  to a kind of unit test coverage. 
It can give you percentages as to how much  of your code it's actually able to check. 
But it's really important that you keep  an eye on that number otherwise you may  have a mistaken idea as to how much coverage you're getting.  Whereas with something like TypeScript  pretty much TypeScript is either  reporting errors or it's all good. 
There's a few kind of flags you can tweak along the way  to give yourself a little bit of flexibility  but it's a little bit more binary in my opinion.  So overall I would say still that  if you're on a React project my opening position  would still probably be to start using Flow,  but pretty much anything else I would go with TypeScript.  But really be prepared to change,  it's something you've gotta try with your team  and see what works best for you in my opinion.  Alright, so just one last thing before we close,  and that is how about Static Types and ECMAScript?  If and how are they gonna relate to one another?  'Cause when I first started looking at these tools  I was like, "Nah, I'm just gonna wait until  "they standardise this stuff in ECMAScripts.  "I don't wanna have to choose between Flow and TypeScript."  And that was probably an extremely naive thing  to think in retrospect. 
And there's kind of good news and bad news on this front.  So it actually turns out that in the ECMAScript spec  there's a section on forbidden extensions  and there's a clause in that section  that talks about how "The Syntactic Grammar  "must not be extended in any manner that allows  "the token : to immediately follow source text  "that matches the BindingIdentifier nonterminal symbol."  And all that really means, at least to my untrained eye,  is that they're saying, "Don't put stuff here,  "we don't put stuff here, don't put stuff here  "if you're thinking of proposing some extensions in future."  They've put space aside so people  don't attempt to jam additional things here.  And that's really nice 'cause it means that,  I'm pretty sure that was put there expressly  for languages like, for type annotations,  for things like TypeScript and Flow. 
So that's the good news. 
The bad news is there hasn't really been anything else.  A couple of years ago there was some proposals  to put some static typing into the language itself  but things have gone a bit quiet on that front.  And Flow and TypeScript have grown  immensely in the meantime with lots of users.  Frankly they've kind of diverged a little bit  and going through the process of trying to reconcile  that divergence or at least find some usable subset  would probably be pretty painful and maybe end up  with a kind of worst of all worlds for everybody.  So at least to my untrained eye looking from the outside  it looks like this stuff's not gonna happen any time soon,  it's probably not gonna be standardised anytime soon.  That's not necessarily a bad thing  'cause these tools are going great guns. 
And at least looking at it from an outsider's perspective  I think that it frees TC39 to think about  other features they want to add to the language,  they can get consultation from the TypeScript  and Flow teams if they want to. 
At the end of the day it's up to those teams  to decide how they incorporate types into it.  It means we can get lots of other awesome things happening  in ECMAScript ongoing without having  to worry too much about this. 
So let's wrap this up. 
Let me just state clearly and unambiguously  I think that right now you should probably start  looking at using a type checker  if you're not already on your project. 
These tools are mature, they've been out there,  and they're awesome. 
I would try Flow in the first instance  if you're working in the Facebook and React ecosystem.  I would try TypeScript for just about anything else  but I would be prepared to change. 
You're gonna have to feel your way through  and see what works best for you and your project.  Unfortunately ECMAScript is probably  not gonna incorporate this stuff anytime soon.  Not necessarily a bad thing, I'm already seeing how  these tools are influencing the ecosystem  but I think it's gonna be more of an  organic thing than anything else. 
Thanks very much everybody. 
If you haven't talked to your team yet  about type checkers I highly encourage you to do so soon.  Thank you very much. 
(audience applause)  (upbeat electronic music)