why static type checking is better
TRANSCRIPT
![Page 1: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/1.jpg)
Why Static Type Checking is Better@AndrewRotaJavaScript Engineer,
![Page 2: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/2.jpg)
With JavaScript...anything is possible
@AndrewRota | #empirejs 2/48
![Page 3: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/3.jpg)
Change all the types...
@AndrewRota | #empirejs
var x; // x starts undefinedtypeof x === 'undefined'
x = 5; // now it's is a numbertypeof x === 'number'
x = 'five'; // now it's a stringtypeof x === 'string'
x = true; // now it's a booleantypeof x === 'boolean'
x = {value: 'five'}; // now it's an objecttypeof x === 'object'
JS
3/48
![Page 4: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/4.jpg)
We have types, but they're not static.(No type is known or declared at compile time)
@AndrewRota | #empirejs 4/48
![Page 5: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/5.jpg)
7 Types in JavaScript
@AndrewRota | #empirejs
Boolean Number String Object
Symbol Null Undefined
5/48
![Page 6: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/6.jpg)
Most code has type expectations...we just don't always acknowledge it.
@AndrewRota | #empirejs
function add(arr) { var sum = 0; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
add([2,3]); // returns 5 as expectedadd(['foo', 'bar']); // returns "0foobar" (expected?)add(null); // Throws exception: cannot read prop 'length' of null
JS
6/48
![Page 7: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/7.jpg)
What to do?
@AndrewRota | #empirejs 7/48
![Page 8: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/8.jpg)
Ad Hoc Runtime Checks
@AndrewRota | #empirejs
function add(arr) { if (!Array.isArray(arr)) return; var sum = 0; for (var i = 0; i < arr.length; i++) { if (typeof arr[i] !== 'number') return; sum += arr[i]; } return sum;}
JS
8/48
![Page 9: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/9.jpg)
Ad Hoc Runtime Checks
@AndrewRota | #empirejs
function add(arr) { if (!Array.isArray(arr)) throw('not an array'); var sum = 0; for (var i = 0; i < arr.length; i++) { if (typeof arr[i] !== 'number') throw('not a number'); sum += arr[i]; } return sum;}
JS
9/48
![Page 10: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/10.jpg)
Type Annotations
@AndrewRota | #empirejs
/** * Add all numbers in an array * * @param {number[]} * @return {number} */function add(arr) { var sum = 0; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
JS
10/48
![Page 11: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/11.jpg)
Type Annotations
Explicit typing...without any checks.
@AndrewRota | #empirejs
/** * Add all numbers in an array * * @param {number[]} * @return {number} */function add(arr) { var sum = 0; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
JS
11/48
![Page 12: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/12.jpg)
Code Reviews !== Type Checks
@AndrewRota | #empirejs 12/48
![Page 13: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/13.jpg)
Type Checking in JavaScript
@AndrewRota | #empirejs 13/48
![Page 14: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/14.jpg)
ActionScriptEarly 2000s | Partially conformed to ECMAScript 4
@AndrewRota | #empirejs
private function add(arr:Array):int{ var sum:int = 0; for (var i:int = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
AS
14/48
![Page 15: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/15.jpg)
Closure Compiler~2009
@AndrewRota | #empirejs
/** * Add all numbers in an array * * @param {number[]} * @return {number} */function add(arr) { var sum = 0; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
JS
15/48
![Page 16: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/16.jpg)
TypeScript2012 | Compiles to JavaScript, optional static typing
@AndrewRota | #empirejs
function add(arr:Array<number>):number{ var sum:number = 0; for (var i:number = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
TS
16/48
![Page 17: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/17.jpg)
Flow2014 | Compiles to JavaScript, optional static typing
@AndrewRota | #empirejs
/* @flow */function add(arr:Array<number>):number{ var sum:number = 0; for (var i:number = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
FLOW
17/48
![Page 18: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/18.jpg)
Flow Comments2015 | Alternative to a transpile step
@AndrewRota | #empirejs
/* @flow */function add(arr/*:Array<number>*/)/*:number*/{ var sum/*:number*/ = 0; for (var i/*:number*/ = 0; i < arr.length; i++) { sum += arr[i]; } return sum;}
JS
18/48
![Page 19: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/19.jpg)
Released Runtime Env. No Transpile Null Checking ES6
Closure Compiler 2009 Java ✓ X Some
TypeScript 2012 JavaScript X X Some
Flow 2014 OCaml X ✓ Some
Flow Comments 2015 OCaml ✓ ✓ Some
@AndrewRota | #empirejs 19/48
![Page 20: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/20.jpg)
Adding Gradual Type Checks
@AndrewRota | #empirejs 20/48
![Page 21: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/21.jpg)
Step 1: Choose a Type Checker
Step 2: Set Up a Transpile Step
Step 3: Add Type Annotations
@AndrewRota | #empirejs 21/48
![Page 22: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/22.jpg)
Step 1: Choose a Type Checker
Step 2: Set Up a Transpile Step
Step 3: Add Type Annotations
@AndrewRota | #empirejs 22/48
![Page 23: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/23.jpg)
TypeScript Flow
TypeScript vs. Flow
@AndrewRota | #empirejs
Released 2012Written in JS: any OSCommunity-provideddeclaration filesAddtional transpiled features(defaults, overloads)
···
·
Released 2014Written in OCaml: OSX, LinuxBuilt-in null handling.Comment-only syntaxavailable
····
23/48
![Page 24: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/24.jpg)
Step 1: Choose a Type Checker
Step 2: Set Up a Transpile Step
Step 3: Add Type Annotations
@AndrewRota | #empirejs 24/48
![Page 25: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/25.jpg)
Setting Up Flow
1. Install Flow from flowtype.org
2. Add transformer ( JSX or Babel ) to your build
@AndrewRota | #empirejs 25/48
![Page 26: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/26.jpg)
Using Flow
1. Run flow check
2. Run build with transformer.
@AndrewRota | #empirejs
Check → Transform
26/48
![Page 27: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/27.jpg)
Using Flow
@AndrewRota | #empirejs 27/48
![Page 28: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/28.jpg)
Setting Up TypeScript
Install TypeScript with npm i ‐g typescript
@AndrewRota | #empirejs 28/48
![Page 29: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/29.jpg)
Using TypeScript
Run tsc myFile.ts
@AndrewRota | #empirejs 29/48
![Page 30: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/30.jpg)
Using TypeScript
@AndrewRota | #empirejs 30/48
![Page 31: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/31.jpg)
Step 1: Choose a Type Checker
Step 2: Set Up a Transpile Step
Step 3: Add Type Annotations
@AndrewRota | #empirejs 31/48
![Page 32: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/32.jpg)
Type InferenceSome of your work's already done!
Flow: property length: Property not found in Number
TypeScript: Property 'length' does not exist on type 'number'
@AndrewRota | #empirejs
var x = 1;x.length;
JS
32/48
![Page 33: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/33.jpg)
Adding Basic Types
Flow: number, string, boolean, void, Array, Function, Object, mixed, any
TypeScript: number, string, boolean, void, Array, Function, Object, any, enum
@AndrewRota | #empirejs
var x:string = 'test'; TS/FLOW
33/48
![Page 34: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/34.jpg)
Arrays
@AndrewRota | #empirejs
var list:number[] = [1,2,3];
var anotherList:Array<number> = [1,2,3];
TS/FLOW
34/48
![Page 35: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/35.jpg)
Union TypesThisType | ThatType
@AndrewRota | #empirejs
var x: number | string = 0;x = 'foo';
TS/FLOW
35/48
![Page 36: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/36.jpg)
Null ChecksFlow has the advantage here
Flow: property x: Property cannot be accessed on possibly null value
TypeScript: no error
@AndrewRota | #empirejs
var x = null;x.foo;
JS
36/48
![Page 37: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/37.jpg)
FunctionsBoth arguments and return values (the function itself)
@AndrewRota | #empirejs
function helloWorld(name: string):string { return 'Hello, ' + name;}function addExclamation(sentence: string):string { return sentence + '!';}addExclamation(helloWorld('EmpireJS'));
TS/FLOW
37/48
![Page 38: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/38.jpg)
Object Literals
@AndrewRota | #empirejs
function doSomething(modelObject: {title: string}) { return modelObject.title;}
doSomething({title: 'My Object!', id: 2, flag: true});
TS/FLOW
38/48
![Page 39: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/39.jpg)
Interfaces
External interfaces via declaration files→ Find TypeScript declarations at definitelytyped.org
@AndrewRota | #empirejs
interface Model { title: string}function doSomething(modelObject: Model) { return modelObject.title;}
doSomething({title: 'My Object!', id: 2, flag: true});
TS/FLOW
39/48
![Page 40: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/40.jpg)
And there's more!
@AndrewRota | #empirejs
ClassesModulesNullable TypesGenericsPolymorphism
·····
40/48
![Page 41: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/41.jpg)
But is it worth it?
@AndrewRota | #empirejs 41/48
![Page 42: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/42.jpg)
Catch More Bugs at Compile Time
Flow: null: This type is incompatible with string
@AndrewRota | #empirejs
function helloWorld(name:string) { return 'Hello, ' + name;}
helloWorld('EmpireJS');helloWorld(null);
FLOW
42/48
![Page 43: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/43.jpg)
Self-Document Code Behavior
@AndrewRota | #empirejs
function flatten (input, shallow, strict) {}
JS
function flatten ( input: Array<any>, shallow: boolean, strict: boolean): Array<any> {}
TS/FLOW
source: http://flowtype.org/docs/underscore.html#_
43/48
![Page 44: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/44.jpg)
Easier to Reason About Code Flow
@AndrewRota | #empirejs
In: Number
Out: String↗
In: String
Out: Object↗
In: Object
Out: Boolean
44/48
![Page 45: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/45.jpg)
- Bertrand Meyer
Correctness
“ The ability of software products to perform their exact tasks, asdefined by their specification.
@AndrewRota | #empirejs 45/48
![Page 46: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/46.jpg)
Tooling
IntelliJ
Sublime
@AndrewRota | #empirejs 46/48
![Page 47: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/47.jpg)
- TypeScript and the Road to 2.0
And someday it might be in JavaScript...
“ The TypeScript team is [...] looking forward to working together goingforward and creating the best tools we can for the JavaScript community.In the long term, we will also be working to fold the best features ofthese tools into ECMAScript, the standard behind JavaScript.
@AndrewRota | #empirejs 47/48
![Page 48: Why Static Type Checking is Better](https://reader030.vdocuments.mx/reader030/viewer/2022032421/55a630181a28ab796d8b4859/html5/thumbnails/48.jpg)
Thanks!
twitter @andrewrota
github github.com/andrewrota