Type Systems On The Web
Michael K Snead
Sr. Architect at Optimum Healthcare IT
Terms and Definitions
- "Statically typed"
Verifies types based on source code
- "Dynamically typed"
Checks type safety at runtime
- "Strongly" (also "Strictly") or "Weakly" typed
No universally accepted definition
Terms and Definitions
- "Nominal types"
If the name/position of the declaration is the same, it's a match.
Two classes can be identical in every way, but are not a match because the name is different.
- "Structural types"
If all properties and methods match, it's the same type.
- "Duck typing"
"Establishing suitability for a given purpose"
Terms and Definitions
- "Sound" (AKA "Provably Correct")
A "sound" type system never permits an incorrect program to pass type checking.
- "Unsound"
An "unsound" type system makes trade-offs for a weaker/less expressive type system with the goal of gaining benefits such as increased productivity.
A brief look at the history of types in JavaScript...
June 2017
June 1997
In June of 1997, the first edition of JavaScript became a standard.
A brief look at the history of types in JavaScript...
June 2017
June 1997
June 1998
ES2
February of 1999
JavaScript 2.0 Draft by Waldemar Horwat at Netscape
function foo(integer i) integer {
return i + 1
}
public function Bar() {
var a; // local to this function
package var b; // package-visible global variable
public var c; // public global variable
}
class Foo {
public method Baz() { } // public class method
}
var any a; // "a" is type "any"
var double b; // "b" is type "double"
February 1999 Draft JavaScript 2.0 https://web.archive.org/web/20000823225606/http://mozilla.org:80/js/language/js20-1999-02-18/types.html
A brief look at the history of types in JavaScript...
June 2017
June 1997
function foo (i : Number) : Number { return 5; }
print("Hi!")
interface IBaz {
function getSprockets() : Number
}
class Bar {
}
class Foo extends Bar implements IBaz {
var sprockets : Number = 4
function Foo() { /* c'tor */ }
function getSprockets() : Number {
return sprockets;
}
}
In July of 2000, Microsoft announces JScript.NET
Compile time + Runtime Checking
What is JScript.NET? https://msdn.microsoft.com/en-us/library/xkx7dfw1(VS.71).aspx
A brief look at the history of types in JavaScript...
June 2017
June 1997
function foo(i : Number) : Number {
return i + 1
}
var a : Number = 1;
public class Bar extends Baz { }
class Foo extends Bar implements IFoo, IFoo2 {
var sprockets : Number;
function Foo() {
}
function GetSprockets() {
return sprockets;
}
}
September of 2003, ActionScript 2.0 is released with compile-time checking
ActionScript 2.0 Language Reference http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/
A brief look at the history of types in JavaScript...
June 2017
June 1997
In 2003 TC-39 progress was all but halted. ES4 was abandoned in favor of ES3.1 > ES5
In 12/2009 ES5 was finally completed
(shipped with IE9 in 2011)
Auth0 "The Real Story Behind ES4" https://auth0.com/blog/the-real-story-behind-es4/
A brief look at the history of types in JavaScript...
June 2017
June 1997
// ES6
class Foo extends Bar {
constructor(sprockets) {
super(sprockets)
this.sprockets = sprockets
}
doWork() { }
static sayHello() { }
get foo() { return true }
set foo(val) { /* ... */ }
}
SoundScript
// Stage 2
class Baz {
widgetCount = 5
static name = "FooBar"
onHandleEvent = () => { /* ... */ }
#secret = 'shhh'
@special
doWork() {
console.log(this.#secret)
}
}
A brief look at the history of types in JavaScript...
June 2017
June 1997
March 2017 WebAssembly reaches cross-browser consensus
A brief look at the history of types in JavaScript...
Additional References
If you want standardized warnings ... we need lots more developer experience to get anywhere near a standard. If you want a static type system -- which means soundness -- then there are big open research problems to solve.
Brendan Eich
Standards, Proposals and the Future
The difference between type annotations as part of the syntax versus the behavior of the engine.
Static type checker for JavaScript
function square(n) {
return n * n // Error!
}
square("2")
Flow understands JavaScript as it's written today, so that much of the time you don't need type annotations.
3 ways to get your "Flow"
- Comments
- Babel
- flow-remove-types*
*Also available as a plugin for rollup, browserify and webpack
import SomeClass from 'some-module'
import type { IFoo } from 'some-module'
export class MyClass<T> implements IFoo {
value: T
constructor(value: T) {
this.value = value
}
get(): T {
return this.value
}
}
import SomeClass from 'some-module'
export class MyClass {
constructor(value) {
this.value = value
}
get() {
return this.value
}
}
(Pass the --pretty option)
3 ways to get your "Flow"
// @flow
/*:: import type { IFoo } from './IFoo'*/
export class MyClass/*::<T> implements IFoo*/ {
/*::value: T */
constructor(value/*: T*/) {
this.value = value
}
get()/*: T*/ {
return this.value
}
}
Using Comments
This means you can use flow without any kind of transpiler/build step.
Let's get started
-
npm init
This creates your package.json -
npm install --save-dev flow-bin
This installs flow -
Add a "flow" script to your package.json
This tells npm how to run flow commands
{
// ...
"scripts": {
"flow": "flow"
}
// ...
}
-
npm run flow init
This sets up a basic .flowconfig -
npm run flow
This starts the flow background process and checks your code - Add // @flow to your code
Flow in your IDE
Flow for ... VS Code?
Flow for ... VS Code?
Install, then click "Reload", then "Reload Window"
Step 1. Install Flow for Visual Studio Code
Flow for ... VS Code?
Step 2. Set your workspace (this project) to use Flow for validation instead of TypeScript for .JS files
Flow for ... VS Code?
Step 2. Set your workspace (this project) to use Flow for validation instead of TypeScript for .JS files
Flow for ... VS Code?
Step 3. Profit
You should now have squigglies, intellisense, etc. provided from Flow.
PS. Some things need saving to update
Flow for ... WebStorm?
WebStorm understands flow annotations out of the box.
Even without flow installed.
To get the best experience, set the JavaScript language to "Flow" and tell WebStorm where the executable is.
File > Settings > Languages & Frameworks > JavaScript
C:\Users\<UserName>\AppData\Roaming\npm\flow.cmd
You can also run "where flow" from Windows.
Didn't find it? npm install -g flow
Flow for ... Visual Studio?
Other ways to work with flow...
Nuclide (built-in)
Atom.io (via flow-ide)
vim (via vim-flow)
emacs, sublime, etc.
Flow at ... runtime?
Check types both at compile and at runtime using babel, exclude the runtime type checks for production.
FlowTyped
// @flow
import jQuery from 'jquery'
jQuery('#id').clicky() // No errors...?
npm install -g flow-typed
flow-typed install
4: jQuery('#id').clicky()
^^^^^^ property `clicky`. Property not found in
4: jQuery('#id').clicky()
^^^^^^^^^^^^^ JQuery
Ahhh, that's better.
Flowgen
npm install -g flowgen
flowgen myfile.d.ts -o myfile.flow.js
Now you can convert TypeScript definitions.
- Take a C# model
- Generate a TypeScript definition
- Convert it to Flow and add it to [libs]
Flow is not perfect.
- Flow Typings has a fraction of the libraries of DefinitelyTyped/Typings
- Flowgen doesn't understand all TypeScript definitions
- If you point flow at node_modules it typechecks everything
- TypeScript often performs better/faster than flow, especially with Microsoft technology
Leveraging other languages for type safety
Static Typing - Compile-to-JS
Fable (F# to JS)
JSIL, SharpKit, Bridge.NET (C#/MSIL to JS)
JSweet (Java to JS)
...and many, many more.
(in particular, Fable can use TypeScript definitions for external JavaScript libraries via ts2fable)
Static Typing - Compile-to-WASM
The Mono team has already started work on a C# to WASM compiler.
Mozilla's goal is for Rust to be a first-class language to compile to WASM:
https://hackernoon.com/compiling-rust-to-webassembly-guide-411066a69fde
...and others
Thanks!
Type Systems On The Web
By Michael Snead
Type Systems On The Web
- 1,540