TypeScript coding JavaScript without the pain @Sander_Mak Luminis Technologies
INTRO @Sander_Mak: Senior Software Engineer at Author: Dutch Java Magazine blog @ branchandbound.net Speaker:
AGENDA Why TypeScript? Language introduction / live-coding TypeScript and Angular Comparison with TS alternatives Conclusion
WHAT'S WRONG WITH JAVASCRIPT? Dynamic typing Lack of modularity Verbose patterns (IIFE)
WHAT'S WRONG WITH JAVASCRIPT? Dynamic typing Lack of modularity Verbose patterns (IIFE) In short: JavaScript development scales badly
WHAT'S GOOD ABOUT JAVASCRIPT? It's everywhere Huge amount of libraries Flexible
WISHLIST Scalable HTML5 clientside development Modular development Easily learnable for Java developers Non-invasive (existing libs, browser support) Long-term vision Clean JS output (exit strategy)
WISHLIST Scalable HTML5 clientside development Modular development Easily learnable for Java developers Non-invasive (existing libs, browser support) Long-term vision Clean JS output (exit strategy) ✓✓✓✓✓✓
2.0 licensed
2.0 licensed
TYPESCRIPT Superset of JavaScript Optionally typed Compiles to ES3/ES5 No special runtime 1.0 in April 2014, future ES6 alignment
TYPESCRIPT Superset of JavaScript Optionally typed Compiles to ES3/ES5 No special runtime 1.0 in April 2014, future ES6 alignment In short: Lightweight productivity booster
GETTING STARTED $ npm install -g typescript $ mv mycode.js mycode.ts $ tsc mycode.ts
GETTING STARTED $ npm install -g typescript $ mv mycode.js mycode.ts $ tsc mycode.ts May even find problems in existing JS!
OPTIONAL TYPES Type annotations > var a = 123 > a.trim() ! TypeError: undefined is not a function JS > var a: string = 123 > a.trim() ! Cannot convert 'number' to 'string'. TS runtime compile-time
OPTIONAL TYPES Type annotations > var a = 123 > a.trim() ! TypeError: undefined is not a function JS > var a: string = 123 > a.trim() ! Cannot convert 'number' to 'string'. TS Type inference > var a = 123 > a.trim() ! The property 'trim' does not exist on value of type 'number'. Types dissapear at runtime
OPTIONAL TYPES Object void boolean integer long short ... String char Type[] any void boolean number string type[]
OPTIONAL TYPES Types are structural rather than nominal TypeScript has function types: var find: (elem: string, elems: string[]) => string = function(elem, elems) { .. }
OPTIONAL TYPES Types are structural rather than nominal TypeScript has function types: var find: (elem: string, elems: string[]) => string = function(elem, elems) { .. }
DEMO: OPTIONAL TYPES code Code: http://bit.ly/tscode
INTERFACES interface MyInterface { // Call signature (param: number): string member: number optionalMember?: number myMethod(param: string): void } ! var instance: MyInterface = ... instance(1)
INTERFACES Use them to describe data returned in REST calls $.getJSON('user/123').then((user: User) => { showProfile(user.details) }
INTERFACES TS interfaces are open-ended: interface JQuery { appendTo(..): .. .. } interface JQuery { draggable(..): .. .. jquery.d.ts } jquery.ui.d.ts
OPTIONAL TYPES: ENUMS enum Language { TypeScript, Java, JavaScript } ! var lang = Language.TypeScript var ts = Language[0] ts === "TypeScript" enum Language { TypeScript = 1, Java, JavaScript } ! var ts = Language[1]
GOING ALL THE WAY Force explicit typing with noImplicitAny var ambiguousType; ! ambiguousType = 1 ambiguousType = "text" noimplicitany.ts $ tsc --noImplicitAny noimplicitany.ts
GOING ALL THE WAY Force explicit typing with noImplicitAny var ambiguousType; ! ambiguousType = 1 ambiguousType = "text" noimplicitany.ts $ tsc --noImplicitAny noimplicitany.ts error TS7005: Variable 'ambiguousType' implicitly has an 'any' type.
TYPESCRIPT CLASSES Can implement interfaces Inheritance Instance methods/members Static methods/members Single constructor Default/optional parameters ES6 class syntax similar different
DEMO: TYPESCRIPT CLASSES code Code: http://bit.ly/tscode
ARROW FUNCTIONS Implicit return No braces for single expression Part of ES6
ARROW FUNCTIONS Implicit return No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); }
ARROW FUNCTIONS Implicit return No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); } (arg1) => arg1.toLowerCase();
ARROW FUNCTIONS Implicit return No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); } (arg1) => arg1.toLowerCase(); Lexically-scoped this (no more 'var that = this')
DEMO: ARROW FUNCTIONS code Code: http://bit.ly/tscode
TYPE DEFINITIONS How to integrate existing JS code? Ambient declarations Any-type :( Type definitions lib.d.ts Separate compilation: tsc --declaration file.ts
TYPE DEFINITIONS DefinitelyTyped.org Community provided .d.ts files for popular JS libs How to integrate existing JS code? Ambient declarations Any-type :( Type definitions lib.d.ts Separate compilation: tsc --declaration file.ts
INTERNAL MODULES module StorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
INTERNAL MODULES module StorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
INTERNAL MODULES module StorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
INTERNAL MODULES module StorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
INTERNAL MODULES TS internal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts
INTERNAL MODULES TS internal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts Can be hierarchical: module Webshop.Cart.Backend { ... }
INTERNAL MODULES TS internal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts Can be hierarchical: module Webshop.Cart.Backend { ... } Combine modules: $ tsc --out main.js main.ts
DEMO: PUTTING IT ALL TOGETHER code Code: http://bit.ly/tscode
EXTERNAL MODULES CommonJS Asynchronous Module Definitions $ tsc --module common main.ts $ tsc --module amd main.ts Combine with module loader
EXTERNAL MODULES 'Standards-based', use existing external modules Automatic dependency management Lazy loading AMD verbose without TypeScript Currently not ES6-compatible
DEMO + + =
DEMO: TYPESCRIPT AND ANGULAR code Code: http://bit.ly/tscode
BUILDING TYPESCRIPT $ tsc -watch main.ts grunt-typescript grunt-ts gulp-type (incremental) gulp-tsc
TOOLING IntelliJ IDEA WebStorm plugin
TYPESCRIPT vs ES6 HARMONY Complete language + runtime overhaul More features: generators, comprehensions, object literals Will take years before widely deployed No typing (possible ES7)
TYPESCRIPT vs COFFEESCRIPT Also a compile-to-JS language More syntactic sugar, still dynamically typed JS is not valid CoffeeScript No spec, definitely no Anders Hejlsberg... Future: CS doesn't track ECMAScript 6 !
TYPESCRIPT vs DART Dart VM + stdlib (also compile-to-JS) Optionally typed Completely different syntax & semantics than JS JS interop through dart:js library ECMA Dart spec
TYPESCRIPT vs CLOSURE COMPILER Google Closure Compiler Pure JS Types in JsDoc comments Less expressive Focus on optimization, dead-code removal
WHO USES TYPESCRIPT? (duh)
CONCLUSION Internal modules Classes/Interfaces Some typing External modules Type defs More typing Generics Type defs -noImplicitAny
CONCLUSION TypeScript allows for gradual adoption Internal modules Classes/Interfaces Some typing External modules Type defs More typing Generics Type defs -noImplicitAny
CONCLUSION Some downsides: Still need to know some JS quirks Current compiler slowish (faster one in the works) External module syntax not ES6-compatible (yet) Non-MS tooling lagging a bit
CONCLUSION High value, low cost improvement over JavaScript Safer and more modular Solid path to ES6
MORE TALKS TypeScript: Wednesday, 11:30 AM, same room !Akka & Event-sourcing Wednesday, 8:30 AM, same room @Sander_Mak Luminis Technologies
RESOURCES Code: http://bit.ly/tscode ! Learn: www.typescriptlang.org/Handbook @Sander_Mak Luminis Technologies

TypeScript: coding JavaScript without the pain

  • 1.
    TypeScript coding JavaScript without the pain @Sander_Mak Luminis Technologies
  • 2.
    INTRO @Sander_Mak: SeniorSoftware Engineer at Author: Dutch Java Magazine blog @ branchandbound.net Speaker:
  • 3.
    AGENDA Why TypeScript? Language introduction / live-coding TypeScript and Angular Comparison with TS alternatives Conclusion
  • 4.
    WHAT'S WRONG WITHJAVASCRIPT? Dynamic typing Lack of modularity Verbose patterns (IIFE)
  • 5.
    WHAT'S WRONG WITHJAVASCRIPT? Dynamic typing Lack of modularity Verbose patterns (IIFE) In short: JavaScript development scales badly
  • 6.
    WHAT'S GOOD ABOUTJAVASCRIPT? It's everywhere Huge amount of libraries Flexible
  • 7.
    WISHLIST Scalable HTML5clientside development Modular development Easily learnable for Java developers Non-invasive (existing libs, browser support) Long-term vision Clean JS output (exit strategy)
  • 8.
    WISHLIST Scalable HTML5clientside development Modular development Easily learnable for Java developers Non-invasive (existing libs, browser support) Long-term vision Clean JS output (exit strategy) ✓✓✓✓✓✓
  • 10.
  • 11.
  • 12.
    TYPESCRIPT Superset ofJavaScript Optionally typed Compiles to ES3/ES5 No special runtime 1.0 in April 2014, future ES6 alignment
  • 13.
    TYPESCRIPT Superset ofJavaScript Optionally typed Compiles to ES3/ES5 No special runtime 1.0 in April 2014, future ES6 alignment In short: Lightweight productivity booster
  • 14.
    GETTING STARTED $npm install -g typescript $ mv mycode.js mycode.ts $ tsc mycode.ts
  • 15.
    GETTING STARTED $npm install -g typescript $ mv mycode.js mycode.ts $ tsc mycode.ts May even find problems in existing JS!
  • 16.
    OPTIONAL TYPES Typeannotations > var a = 123 > a.trim() ! TypeError: undefined is not a function JS > var a: string = 123 > a.trim() ! Cannot convert 'number' to 'string'. TS runtime compile-time
  • 17.
    OPTIONAL TYPES Typeannotations > var a = 123 > a.trim() ! TypeError: undefined is not a function JS > var a: string = 123 > a.trim() ! Cannot convert 'number' to 'string'. TS Type inference > var a = 123 > a.trim() ! The property 'trim' does not exist on value of type 'number'. Types dissapear at runtime
  • 18.
    OPTIONAL TYPES Objectvoid boolean integer long short ... String char Type[] any void boolean number string type[]
  • 19.
    OPTIONAL TYPES Typesare structural rather than nominal TypeScript has function types: var find: (elem: string, elems: string[]) => string = function(elem, elems) { .. }
  • 20.
    OPTIONAL TYPES Typesare structural rather than nominal TypeScript has function types: var find: (elem: string, elems: string[]) => string = function(elem, elems) { .. }
  • 21.
    DEMO: OPTIONAL TYPES code Code: http://bit.ly/tscode
  • 22.
    INTERFACES interface MyInterface{ // Call signature (param: number): string member: number optionalMember?: number myMethod(param: string): void } ! var instance: MyInterface = ... instance(1)
  • 23.
    INTERFACES Use themto describe data returned in REST calls $.getJSON('user/123').then((user: User) => { showProfile(user.details) }
  • 24.
    INTERFACES TS interfacesare open-ended: interface JQuery { appendTo(..): .. .. } interface JQuery { draggable(..): .. .. jquery.d.ts } jquery.ui.d.ts
  • 25.
    OPTIONAL TYPES: ENUMS enum Language { TypeScript, Java, JavaScript } ! var lang = Language.TypeScript var ts = Language[0] ts === "TypeScript" enum Language { TypeScript = 1, Java, JavaScript } ! var ts = Language[1]
  • 26.
    GOING ALL THEWAY Force explicit typing with noImplicitAny var ambiguousType; ! ambiguousType = 1 ambiguousType = "text" noimplicitany.ts $ tsc --noImplicitAny noimplicitany.ts
  • 27.
    GOING ALL THEWAY Force explicit typing with noImplicitAny var ambiguousType; ! ambiguousType = 1 ambiguousType = "text" noimplicitany.ts $ tsc --noImplicitAny noimplicitany.ts error TS7005: Variable 'ambiguousType' implicitly has an 'any' type.
  • 28.
    TYPESCRIPT CLASSES Canimplement interfaces Inheritance Instance methods/members Static methods/members Single constructor Default/optional parameters ES6 class syntax similar different
  • 29.
    DEMO: TYPESCRIPT CLASSES code Code: http://bit.ly/tscode
  • 30.
    ARROW FUNCTIONS Implicitreturn No braces for single expression Part of ES6
  • 31.
    ARROW FUNCTIONS Implicitreturn No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); }
  • 32.
    ARROW FUNCTIONS Implicitreturn No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); } (arg1) => arg1.toLowerCase();
  • 33.
    ARROW FUNCTIONS Implicitreturn No braces for single expression Part of ES6 function(arg1) { return arg1.toLowerCase(); } (arg1) => arg1.toLowerCase(); Lexically-scoped this (no more 'var that = this')
  • 34.
    DEMO: ARROW FUNCTIONS code Code: http://bit.ly/tscode
  • 35.
    TYPE DEFINITIONS Howto integrate existing JS code? Ambient declarations Any-type :( Type definitions lib.d.ts Separate compilation: tsc --declaration file.ts
  • 36.
    TYPE DEFINITIONS DefinitelyTyped.org Community provided .d.ts files for popular JS libs How to integrate existing JS code? Ambient declarations Any-type :( Type definitions lib.d.ts Separate compilation: tsc --declaration file.ts
  • 37.
    INTERNAL MODULES moduleStorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
  • 38.
    INTERNAL MODULES moduleStorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
  • 39.
    INTERNAL MODULES moduleStorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
  • 40.
    INTERNAL MODULES moduleStorageModule { export interface Storage { store(content: string): void } ! var privateKey = 'storageKey'; export class LocalStorage implements Storage { store(content: string): void { localStorage.setItem(privateKey, content); } } ! export class DevNullStorage implements Storage { store(content: string): void { } } } ! var storage: StorageModule.Storage = new StorageModule.LocalStorage(); storage.store('testing');
  • 41.
    INTERNAL MODULES TSinternal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts
  • 42.
    INTERNAL MODULES TSinternal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts Can be hierarchical: module Webshop.Cart.Backend { ... }
  • 43.
    INTERNAL MODULES TSinternal modules are open-ended: ! module Webshop { export class Cart { .. } } /// <reference path="cart.ts" /> module Webshop { export class Catalog { .. } cart.ts } main.ts Can be hierarchical: module Webshop.Cart.Backend { ... } Combine modules: $ tsc --out main.js main.ts
  • 44.
    DEMO: PUTTING ITALL TOGETHER code Code: http://bit.ly/tscode
  • 45.
    EXTERNAL MODULES CommonJS Asynchronous Module Definitions $ tsc --module common main.ts $ tsc --module amd main.ts Combine with module loader
  • 46.
    EXTERNAL MODULES 'Standards-based',use existing external modules Automatic dependency management Lazy loading AMD verbose without TypeScript Currently not ES6-compatible
  • 47.
  • 48.
    DEMO: TYPESCRIPT ANDANGULAR code Code: http://bit.ly/tscode
  • 49.
    BUILDING TYPESCRIPT $tsc -watch main.ts grunt-typescript grunt-ts gulp-type (incremental) gulp-tsc
  • 50.
    TOOLING IntelliJ IDEA WebStorm plugin
  • 51.
    TYPESCRIPT vs ES6HARMONY Complete language + runtime overhaul More features: generators, comprehensions, object literals Will take years before widely deployed No typing (possible ES7)
  • 52.
    TYPESCRIPT vs COFFEESCRIPT Also a compile-to-JS language More syntactic sugar, still dynamically typed JS is not valid CoffeeScript No spec, definitely no Anders Hejlsberg... Future: CS doesn't track ECMAScript 6 !
  • 53.
    TYPESCRIPT vs DART Dart VM + stdlib (also compile-to-JS) Optionally typed Completely different syntax & semantics than JS JS interop through dart:js library ECMA Dart spec
  • 54.
    TYPESCRIPT vs CLOSURECOMPILER Google Closure Compiler Pure JS Types in JsDoc comments Less expressive Focus on optimization, dead-code removal
  • 55.
  • 56.
    CONCLUSION Internal modules Classes/Interfaces Some typing External modules Type defs More typing Generics Type defs -noImplicitAny
  • 57.
    CONCLUSION TypeScript allowsfor gradual adoption Internal modules Classes/Interfaces Some typing External modules Type defs More typing Generics Type defs -noImplicitAny
  • 58.
    CONCLUSION Some downsides: Still need to know some JS quirks Current compiler slowish (faster one in the works) External module syntax not ES6-compatible (yet) Non-MS tooling lagging a bit
  • 59.
    CONCLUSION High value,low cost improvement over JavaScript Safer and more modular Solid path to ES6
  • 60.
    MORE TALKS TypeScript: Wednesday, 11:30 AM, same room !Akka & Event-sourcing Wednesday, 8:30 AM, same room @Sander_Mak Luminis Technologies
  • 61.
    RESOURCES Code: http://bit.ly/tscode ! Learn: www.typescriptlang.org/Handbook @Sander_Mak Luminis Technologies