the flavor of typescript

71
The flavor of TypeScript a hands-on guide September 2016

Upload: dmitry-sheiko

Post on 15-Apr-2017

193 views

Category:

Software


0 download

TRANSCRIPT

Page 1: The Flavor of TypeScript

The flavor of TypeScripta hands-on guide

September 2016

Page 2: The Flavor of TypeScript

I'm Dmitry Sheiko, a web developer, blogger, open source contributor.

@sheikohttp://dsheiko.com

Page 3: The Flavor of TypeScript

TypeScript is a superset of JavaScript

that enables language features such as…

Page 4: The Flavor of TypeScript

static typing, interfaces,

abstract classes, member visibility

and more

Page 5: The Flavor of TypeScript

TypeScript compiles to JavaScript

(ES5 or higher)

Page 6: The Flavor of TypeScript

Agitated? Let’s give it a start

Page 7: The Flavor of TypeScript

npm install typescript -gInstall typescript

Page 8: The Flavor of TypeScript

{ "compilerOptions": {

"target": "ES5", "module": "commonjs",

"moduleResolution": "node"outDir": "build/"

}, "files": [ "./app.ts" ]}

Create tsconfig.json

Page 9: The Flavor of TypeScript

function append( line: string ): string { return "suffix" + line;}

var res: string = append( "a string" );

Write test module app.ts

Page 10: The Flavor of TypeScript

tscCompile typescript

Page 11: The Flavor of TypeScript

function append(line) { return "suffix" + line;}var res = append("a string");

Observe the generated build/app.js

Page 12: The Flavor of TypeScript

TypeScript has simply removed the typing

Page 13: The Flavor of TypeScript

However if in our source we try to give a wrong type the IDE warns us:

Page 14: The Flavor of TypeScript

TypeScript compiler also warns us:tsc

src/app.ts(5,27): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.

Page 15: The Flavor of TypeScript

How does TypeScript deal with modules?

Page 16: The Flavor of TypeScript

import { foo } from "./foo";console.log( foo );

TypeScript accepts ES6 module syntax (https://www.typescriptlang.org/docs/handbook/modules.html)app.ts

export var foo: string = "a string";foo.ts

Page 17: The Flavor of TypeScript

"use strict";var foo_1 = require("./foo");console.log(foo_1.foo);

According to our tsconfig.json configuration TypeScript compiles them in CommonJS modules:app.ts

"use strict";exports.foo = "a string";

foo.ts

Page 18: The Flavor of TypeScript

We can bundle TypeScript-generated

modules with Browserfy

(http://browserify.org/)

Page 19: The Flavor of TypeScript

Alternatively we can load them

asynchronously with e.g. SystemJS

(https://github.com/systemjs/systemjs)

Page 20: The Flavor of TypeScript

With TypeScript one may write in latest JavaScript syntax (ES2015/2016).

TypeScript can compile to JavaScript suitable for old

browsers.

Page 21: The Flavor of TypeScript

Variables and scoping

Page 22: The Flavor of TypeScript

if ( true ) { let foo = "foo";}console.log( foo ); // undefined

Block scope

const foo = "foo";foo = "bar"; // ERROR

Constants

Page 23: The Flavor of TypeScript

Template literal

Page 24: The Flavor of TypeScript

let foo = `linelineline`;

Multi-line strings

let foo = "foo", bar = "bar", str = ` ${foo}, ${bar}`;console.log( str ); // foo, bar

Template literal

Page 25: The Flavor of TypeScript

Arrow functions

Page 26: The Flavor of TypeScript

this.foo = 1;let res = [ 1, 2, 3 ].map(( n ) => { return this.foo + n;});console.log( res ); // 2, 3, 4

Shorter syntax where the callback keeps outer context

this.foo = 1;let res = [ 1, 2, 3 ].map( n => this.foo + n );console.log( res ); // 2, 3, 4

Can be even shorter

Page 27: The Flavor of TypeScript

Classes

Page 28: The Flavor of TypeScript

class Foo { bar() { return "bar"; } static baz() { return "baz"; }}

console.log( Foo.baz() );let foo = new Foo();console.log( foo.bar() );

Syntactic sugar over prototypes

Page 29: The Flavor of TypeScript

class Foo { bar() { return "bar"; }}class Baz extends Foo {}let baz = new Baz();console.log( baz.bar() );

Class-based inheritance

Page 30: The Flavor of TypeScript

class Foo { constructor( arg ) { this.arg = arg; }}class Bar extends Foo { constructor( arg ) { super( arg ); }}let bar = new Bar( "arg" );console.log( bar.arg );

Constructor function

Page 31: The Flavor of TypeScript

Leaner Object Literals

Page 32: The Flavor of TypeScript

let baz = "baz";let obj = { foo: "foo", bar() { return "bar"; }, baz}console.log( obj ); // Object { foo="foo", baz="baz", bar=function()}

ES6 method definition and default value

Page 33: The Flavor of TypeScript

Arguments

Page 34: The Flavor of TypeScript

function foo( start = 0, end = 1 ) { console.log( start, end );}

Named parameters

function foo({ start = 0, end = 1 } = {}) { console.log( start, end );}

Optional parameters

Page 35: The Flavor of TypeScript

function log( msg, ...args ) { console.log( msg, args[ 0 ], "..." );}log( "passing nums", 1, 2, 3 ); // passing nums 1...

Rest parameters

Page 36: The Flavor of TypeScript

function save( foo, bar, baz ) { console.log( foo, bar, baz );}let csv = "foo,bar,baz".split( "," );save( ...csv ); // foo bar baz

Spread operator

Page 37: The Flavor of TypeScript

Collections

Page 38: The Flavor of TypeScript

const map = new Map();map.set( "aKey", "a value" );map.get( "aKey" ); // "a value" valuemap.size; // 1

// Key can be an objectmap.set( window, "a value" );

map.forEach(( value, key ) => { //..});map.has( "aKey" ); // truemap.delete( "aKey" );map.clear();

Maps

Page 39: The Flavor of TypeScript

const set = new Set([ 1, 2, 3, 4 ]);

set.add( 5 );set.has( 5 ); // trueset.size; // 5set.delete( 5 );set.size; // 4

set.forEach( console.log ); // 1, 2, 3, 4set.clear();set.size; // 0

Sets

Page 40: The Flavor of TypeScript

Symbols

Page 41: The Flavor of TypeScript

const ERR_CODE = { TYPE_ERROR: Symbol(), SYNTAX_ERROR: Symbol()}

console.log( ERR_CODE.TYPE_ERROR === ERR_CODE.TYPE_ERROR ); // true

A symbol is a unique and immutable data type

Page 42: The Flavor of TypeScript

Destructuring

Page 43: The Flavor of TypeScript

let foo, bar, baz;[foo, bar, baz] = "foo,bar,baz".split( "," );

Array destructuring

let { foo, bar } = obj;// foo = "foo", bar = "bar"

Object destructuring

Page 44: The Flavor of TypeScript

let obj = { foo: "foo", bar: "bar" };let { foo: f, bar: b} = obj; // f = "foo", b = "bar"

Aliasing during destructuring

let el = document.getElementById( "#foo" );const { querySelector, querySelectorAll } = el;querySelector( ".class" );

Extracting shorteners

Page 45: The Flavor of TypeScript

Decorators

Page 46: The Flavor of TypeScript

Decorators allow to annotate or modify classes and class

members

Page 47: The Flavor of TypeScript

{ "compilerOptions": {

… "emitDecoratorMetadata": true, "experimentalDecorators": true }, …}

Add to tsconfig.json

Page 48: The Flavor of TypeScript

function Mixin( data ) { return function( target ){ Object.assign( target.prototype, data ); };}

@Mixin({ bar: "bar"})class Foo {}let foo = new Foo();console.log( foo.bar );

Modifying the prototype

Page 49: The Flavor of TypeScript

function Readonly( target, key, descriptor ) { descriptor.writable = false; return descriptor;}

class Foo{ @Readonly bar(){ }}let foo = new Foo();foo.bar ="bar"; // ERROR

Annotating a member

Page 50: The Flavor of TypeScript

Extras

Page 51: The Flavor of TypeScript

function test(){ let arr = Array.from( arguments ); Array.isArray( arr ); // true arr.includes( 2 ); // true arr.find( n => n === 2 ); // 2}test( 1, 2, 3 );

Array extras

let foo = { foo: "foo" };Object.assign( foo, { bar: "bar" } );foo; // { foo: "foo", bar: "bar" }

Object.assign

Page 52: The Flavor of TypeScript

TypeScript enhancement

Page 53: The Flavor of TypeScript

Interfaces

Page 54: The Flavor of TypeScript

interface Rectangle { width: number; height: number; calcArea(): number;}

class Square implements Rectangle { width: number; height: number; calcArea() { this.width * this.height; }}

Interface to implement

Page 55: The Flavor of TypeScript

interface DataMap { [key: string]: any;}

function stringify( data: DataMap ){ return JSON.stringify( data );}

stringify({ foo: [ 1,2 ] });

Interface in type annotation

Page 56: The Flavor of TypeScript

interface DataMap<Val> { [key: string]: Val;}

function stringify( data: DataMap<string> ){ return JSON.stringify( data );}

stringify({ foo: "foo" });

Interface with a generic

Page 57: The Flavor of TypeScript

Abstract classes and member visibility

Page 58: The Flavor of TypeScript

abstract class Foo { protected bar(){}}

class Bar extends Foo { private secret: string = "secret"; public quiz(){ return this.bar(); }}

Abstract, public, private, and protected modifiers

Page 59: The Flavor of TypeScript

Parameter properties

Page 60: The Flavor of TypeScript

class Foo { public constructor( public arg: string = "default"){ }}let foo = new Foo();console.log( foo.arg ); // default

Parameter properties let you create and initialize a member in one place

Page 61: The Flavor of TypeScript

class Foo { private bar: string = "bar"; baz: number[] = [ 1, 2 ]; static quiz: boolean = true;}

We cannot declare properties in ES6, but we can with TypeScript

Page 62: The Flavor of TypeScript

Casting types

Page 63: The Flavor of TypeScript

function geInput(): HTMLInputElement { let el = <HTMLInputElement> document.querySelector( "input" );}

document.querySelector returns always abstract Element type regardless of the selector. If you expect a concrete implementation of Element (e.g. HTMLInputElement), you can cast it.

Page 64: The Flavor of TypeScript

Union type

Page 65: The Flavor of TypeScript

function validate( spec: string | string[] ): boolean { if ( !Array.isArray( spec ) ) { spec = <string[]>Array.of( spec ); } return spec.every( isSpecValid );}

Here parameter spec is allowed to be either a string or an array of strings

Page 66: The Flavor of TypeScript

We can use in TypeScript existing JavaScript libraries

Page 67: The Flavor of TypeScript

What about external library interfaces?

Page 68: The Flavor of TypeScript

npm install typings --globalInstall Typings

typings search --name backbone

Search for available type definitions

typings install dt~backbone --global --save

Install definitions

Page 69: The Flavor of TypeScript

{ …, "files": [ "./typings/index.d.ts", … ]}

Add typings index to tsconfig.json

Page 70: The Flavor of TypeScript

class View extends Backbone.View { events: { "click button": "onClick" } onClick( e: Event ) { e.preventDefault(); }}

Now we can use a library, e.g. BackboneJS

Page 71: The Flavor of TypeScript

Thank you!