Slide 1

Slide 1 text

Introduction to TypeScript Samantha Quiñones, Open West 2016

Slide 2

Slide 2 text

Samantha Quiñones Principal Software Engineer Code and Community Champion AOL Inc. @ieatkillerbees @squinones ɂ http://squinones.github.io ɔ https://joind.in/talk/bedf8

Slide 3

Slide 3 text

What is Typescript? • Superset of JavaScript (all valid JavaScript is valid TypeScript) • Provides features from upcoming ECMAScript standards versions • Adds optional strict typing • Adopted by a number of projects, Angular 2 prominently • Microsoft • http://www.typescriptlang.org

Slide 4

Slide 4 text

Why use TypeScript? • You want to use features of modern EMCA standards now • You want to make your complex JavaScript apps more robust

Slide 5

Slide 5 text

About You • You are familiar with JavaScript • You have not worked extensively with statically typed languages • You are familiar with the build pipeline tools appropriate to your projects or environment (or are willing to talk after the session)

Slide 6

Slide 6 text

Things I Won’t Cover • Workflow • Decorators • JSX

Slide 7

Slide 7 text

Static vs Dynamic Typing […] strong typing is modestly better than weak typing, and […] static typing is also somewhat better than dynamic typing. Ray, B., Posnett, D., Filkov, V., Devanbu, P. T. (2014). A Large Scale Study of Programming Languages and Code Quality in Github

Slide 8

Slide 8 text

Dynamic Typing function div(a, b) { return a/b; } console.log(div("a", "b"));

Slide 9

Slide 9 text

Static Typing function div(a:number, b:number): number { return a/b; } console.log(div("a", "b"));

Slide 10

Slide 10 text

Static Typing function div(a:number, b:number): number { return a/b; } console.log(div("a", "b")); function div(a, b) { return a / b; } console.log(div("a", "b")); //# sourceMappingURL=typed.js.map ⊗

Slide 11

Slide 11 text

Static Typing function div(a:number, b:number): number { return a/b; } console.log(div("a", "b")); function div(a, b) { return a / b; } console.log(div("a", "b")); //# sourceMappingURL=typed.js.map ⊗ > $ tsc examples/typed.ts examples/typed.ts(5,17): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Slide 12

Slide 12 text

Reasons I Prefer Static Typing • Get more out of my IDE (I’m looking at you, JetBrains) • Slightly more verbose code is more explicit and I believe in 
 explicit > implicit • Allows the potential for fewer tedious tests. But testing is still vital.

Slide 13

Slide 13 text

Basic Types - Booleans let isBoolean:boolean = true;

Slide 14

Slide 14 text

Basic Types - Numbers let decimal:number = 42; let hexadecimal:number = 0x2A; let binary:number = 0b101010; let octal:number = 0o52;

Slide 15

Slide 15 text

Basic Types - Strings let firstName:string = "Samantha"; let greeting:string = `Hello, my name is ${ firstName }!`; let greeting:string = "Hello, my name is " + firstName + "!";

Slide 16

Slide 16 text

Basic Types - Arrays let names:string[] = ["Joe", "Sally"]; let ages:number[] = [28, 32]; let heights:Array = [71, 66];

Slide 17

Slide 17 text

Basic Types - Tuples let coords:[number, number] = [42, 21]; let params:[string, number] = ["height", 72];

Slide 18

Slide 18 text

Basic Types - Enums enum Status {Inactive, Active} let status: Status = Status.Inactive;

Slide 19

Slide 19 text

Basic Types - Void let nothing:void = undefined; function doNothing(): void { // do nothing! }

Slide 20

Slide 20 text

The “Any” Type let anything:any = "foo";

Slide 21

Slide 21 text

The “Any” Type let anything:any = "foo"; function combine(a, b) { return a + b; } let foo = 42; let bar = "fred"; console.log(combine(foo, bar)); function combine(a:any, b:any):any { return a + b; } let foo:number = 42; let bar:string = "fred"; console.log(combine(foo, bar));

Slide 22

Slide 22 text

Type Assertions let anyValue: any = "This value is a string!"; let stringLength: number = anyValue.length; // angle bracket style let stringLength: number = (anyValue as string).length; // JSX-style

Slide 23

Slide 23 text

Variables • var - execution/global scope • let - block/local scope

Slide 24

Slide 24 text

let vs. var function blockscope() { for( let i = 0; i < 5; i++ ) { console.log(i); } console.log(i); } function executionscope() { for( var i = 0; i < 5; i++ ) { console.log(i) } console.log(i); }

Slide 25

Slide 25 text

let vs. var for (var i = 0; i < 10; i++) { setTimeout(function() {console.log(i); }, 100 * i); }

Slide 26

Slide 26 text

let vs. var for (var i = 0; i < 10; i++) { setTimeout(function() {console.log(i); }, 100 * i); } > $ node examples/letloop.js 10 10 10 10 10 10 10 10 10 10

Slide 27

Slide 27 text

let vs. var for (var i = 0; i < 10; i++) { (function(i) { setTimeout(function() { console.log(i); }, 100 * i); })(i); }

Slide 28

Slide 28 text

let vs. var for (var i = 0; i < 10; i++) { (function(i) { setTimeout(function() { console.log(i); }, 100 * i); })(i); } > $ node examples/letloop.js 0 1 2 3 4 5 6 7 8 9

Slide 29

Slide 29 text

let vs. var for (let i = 0; i < 10 ; i++) { setTimeout(function() {console.log(i); }, 100 * i); }

Slide 30

Slide 30 text

let vs. var > $ node examples/letloop.js 0 1 2 3 4 5 6 7 8 9 for (let i = 0; i < 10 ; i++) { setTimeout(function() {console.log(i); }, 100 * i); }

Slide 31

Slide 31 text

let vs. var for (let i = 0; i < 10 ; i++) { setTimeout(function() {console.log(i); }, 100 * i); } var _loop_1 = function(i) { setTimeout(function () { console.log(i); }, 100 * i); }; for (var i = 0; i < 10; i++) { _loop_1(i); }

Slide 32

Slide 32 text

Constants var foo = 42; function timesFoo(a) { return foo * a; } console.log(timesFoo(2)); const foo:number = 42; function timesFoo(a:number): number { return foo * a; } console.log(timesFoo(2));

Slide 33

Slide 33 text

Constants const foo:number = 42; function timesFoo(a:number): number { return foo * a; } foo = 1701; console.log(timesFoo(2)); var foo = 42; function timesFoo(a) { return foo * a; } foo = 1701; console.log(timesFoo(2)); > $ tsc examples/consts.ts examples/consts.ts(8,1): error TS2450: Left- hand side of assignment expression cannot be a constant.

Slide 34

Slide 34 text

Interfaces interface Meat { isCooked:boolean; sourceAnimal:string; } function cookMeat(meat:Meat): Meat { meat.isCooked = true; return meat; } let sirloin:Meat = { isCooked: false, sourceAnimal: "cattle" }; cookMeat(sirloin); console.log(sirloin.isCooked);

Slide 35

Slide 35 text

Interfaces - Optional Properties interface Meat { isCooked:boolean; isGame:boolean; sourceAnimal:string; gaminess?:number; } function cookMeat(meat:Meat):Meat { meat.isCooked = true; return meat; } let sirloin:Meat = { isCooked: false, isGame:false, sourceAnimal: "cattle" }; cookMeat(sirloin); console.log(sirloin.isCooked); let venison:Meat = { isCooked: false, isGame:true, sourceAnimal: "deer", gaminess: 3 }; cookMeat(venison); console.log(venison.isCooked);

Slide 36

Slide 36 text

Interfaces - Undefined Properties let venison:Meat = { isCooked: false, isGame:true, sourceAnimal: "deer", gameiness: 3 }; cookMeat(venison); console.log(venison.isCooked); examples/recipes/meat.ts(23,5): error TS2322: Type '{ isCooked: boolean; isGame: boolean; sourceAnimal: string; gameiness: number; }' is not assignable to type 'Meat'. Object literal may only specify known properties, and 'gameiness' does not exist in type 'Meat'.

Slide 37

Slide 37 text

Interfaces - Index Signatures interface Meat { isCooked:boolean; isGame:boolean; sourceAnimal:string; gaminess?:number; [otherProperty: string]: any; } let ChickenBreast:Meat = { isCooked: false, isGame: false, sourceAnimal: "chicken", skinless: true };

Slide 38

Slide 38 text

Interfaces - Function Interfaces interface Ingredient { name: string; } interface MixedIngredient { ingredients: Ingredient[]; } interface MixFunction { (ingredients:Ingredient[], speed:number): MixedIngredient; } let mixer:MixFunction = function (ingredients:Ingredient[], speed:number): MixedIngredient { return { ingredients: ingredients }; }; let mixed = mixer([{name: "flour"}, {name: "sugar"}], 10); console.log(mixed);

Slide 39

Slide 39 text

Interfaces - Indexed Types interface Ingredient { name: string; } interface IngredientList { [index: number]: Ingredient } interface MixFunction { (ingredients:Ingredient[], speed:number): any; } interface MixFunction2 { (ingredients:IngredientList, speed: number): any; }

Slide 40

Slide 40 text

Interfaces - Indexed Types interface Ingredient { name: string, quantity: number, unit: string } interface RecipeDictionary { [index: string]: Ingredient }

Slide 41

Slide 41 text

Interfaces - Indexed Types interface Ingredient { name: string, quantity: number, unit: string } interface RecipeDictionary { [index: string]: Ingredient name: string; } > $ tsc examples/dictionary.ts examples/dictionary.ts(9,5): error TS2411: Property 'name' of type 'string' is not assignable to string index type 'Ingredient'.

Slide 42

Slide 42 text

Interface Extension interface Meat { isCooked:boolean; sourceAnimal:string; [otherProperty: string]: any; } interface Game extends Meat { gaminess:number; } let GroundChuck:Meat = { isCooked:false, sourceAnimal: "cattle" }; let DuckBreast:Game = { isCooked:false, sourceAnimal: "duck", gaminess: 3 };

Slide 43

Slide 43 text

Implementing Interfaces interface Mixer { mix:MixFunction, clean(): void } class KitchenAid implements Mixer { } > $ tsc examples/implementing-interfaces.ts examples/implementing-interfaces.ts(18,7): error TS2420: Class 'KitchenAid' incorrectly implements interface 'Mixer'. Property 'mix' is missing in type 'KitchenAid'.

Slide 44

Slide 44 text

Implementing Interfaces interface Mixer { mix:MixFunction, clean(): void } class KitchenAid implements Mixer { mix(ingredients:Ingredient[], speed:number): MixedIngredient { return { ingredients: ingredients }; }; clean(): void { // } }

Slide 45

Slide 45 text

Classes class Ingredient { name:string; unit:string; quantity:number; constructor(name:string, unit:string, quantity:number) { this.name = name; this.unit = unit; this.quantity = quantity; } recipeString(): string { return `${this.name} - ${this.quantity} ${this.unit}`; } } let flour = new Ingredient("flour", "cup", 1);

Slide 46

Slide 46 text

Classes var Ingredient = (function () { function Ingredient(name, unit, quantity) { this.name = name; this.unit = unit; this.quantity = quantity; } Ingredient.prototype.recipeString = function () { return this.name + " - " + this.quantity + " " + this.unit; }; return Ingredient; })(); var flour = new Ingredient("flour", "cup", 1);

Slide 47

Slide 47 text

Inheritance in JavaScript • JavaScript uses prototypal inheritance • Inherited properties come from a linked object (the prototype) • The prototype model can be used to implement classical inheritance • ES6 (and TypeScript) introduce a “class” keyword that provides syntactic sugar for creating classical inheritance chains using prototypes

Slide 48

Slide 48 text

Classes - Inheritance enum FlourType { White, Wheat, Rye, Corn } class Flour extends Ingredient { type:FlourType; constructor(name:string, unit:string, quantity:number, type:FlourType) { super(name, unit, quantity); this.type = type; } } let wheatFlour = new Flour("flour", "cup", 1, FlourType.Wheat);

Slide 49

Slide 49 text

Classes - Inheritance var FlourType; (function (FlourType) { FlourType[FlourType["White"] = 0] = "White"; FlourType[FlourType["Wheat"] = 1] = "Wheat"; FlourType[FlourType["Rye"] = 2] = "Rye"; FlourType[FlourType["Corn"] = 3] = "Corn"; })(FlourType || (FlourType = {})); var Flour = (function (_super) { __extends(Flour, _super); function Flour(name, unit, quantity, type) { _super.call(this, name, unit, quantity); this.type = type; } return Flour; })(Ingredient); var wheatFlour = new Flour("flour", "cup", 1, FlourType.Wheat); //# sourceMappingURL=inheritance.js.map

Slide 50

Slide 50 text

Classes - Abstracts abstract class Ingredient { constructor(protected name:string) {} abstract printRecipeString(): string; } class OliveOil extends Ingredient { constructor() { super("Olive Oil"); } printRecipeString():string { return `${this.name}`; } }

Slide 51

Slide 51 text

Classes - Extending class Ingredient { name:string; unit:string; quantity:number; } interface Oil extends Ingredient { viscosity:number; }

Slide 52

Slide 52 text

Classes - Visibility class Ingredient { name:string; unit:string; quantity:number; } class Ingredient { public name:string; public unit:string; public quantity:number; }

Slide 53

Slide 53 text

Classes - Visibility class Ingredient { name:string; unit:string; quantity:number; } class Ingredient { public name:string; public unit:string; public quantity:number; } == • Public properties are visible to any caller • Protected properties are visible to a class instance and its children • Private properties are visible only to a class instance

Slide 54

Slide 54 text

Classes - Private Members class Ingredient { private _name:string; private _unit:string; private _quantity:number; constructor(name:string, unit:string, quantity:number) { this._name = name; this._unit = unit; this._quantity = quantity; } } let butter= new Ingredient("butter", "tbsp", 2); butter._unit = "cup"; > $ tsc examples/classes/private.ts examples/classes/private.ts(14,1): error TS2341: Property '_unit' is private and only accessible within class 'Ingredient'.

Slide 55

Slide 55 text

Classes - Private Members class Ingredient { private _name:string; constructor(name:string) { this._name = name; } } class Butter extends Ingredient { constructor() { super(“Butter"); } } class Condiment { private _name:string; constructor(name:string) { this._name = name; } } let ingredients:Ingredient[] = [new Butter(), new Condiment("Ketchup")];

Slide 56

Slide 56 text

Classes - Private Members class Ingredient { private _name:string; constructor(name:string) { this._name = name; } } class Butter extends Ingredient { constructor() { super(“Butter"); } } class Condiment { private _name:string; constructor(name:string) { this._name = name; } } let ingredients:Ingredient[] = [new Butter(), new Condiment("Ketchup")]; > $ tsc examples/classes/private.ts examples/classes/private.ts(23,5): error TS2322: Type '(Butter | Condiment)[]' is not assignable to type 'Ingredient[]'. Type 'Butter | Condiment' is not assignable to type 'Ingredient'. Type 'Condiment' is not assignable to type 'Ingredient'. Types have separate declarations of a private property '_name'.

Slide 57

Slide 57 text

Classes - Protected Members class Ingredient { private _name:string; private _unit:string; constructor(name:string) { this._name = name; } } class Butter extends Ingredient { constructor() { super("Butter"); this._unit = "tbsp"; } } let butter = new Ingredient("butter"); > $ tsc examples/classes/protected.ts examples/classes/protected.ts(12,9): error TS2341: Property '_unit' is private and only accessible within class 'Ingredient'.

Slide 58

Slide 58 text

Classes - Protected Members > $ tsc examples/classes/protected.ts examples/classes/protected.ts(17,1): error TS2445: Property '_unit' is protected and only accessible within class 'Ingredient' and its subclasses. class Ingredient { private _name:string; protected _unit:string; constructor(name:string) { this._name = name; } } class Butter extends Ingredient { constructor() { super("Butter"); this._unit = "tbsp"; } } let butter= new Ingredient("butter"); butter.unit = "cup";

Slide 59

Slide 59 text

Classes - Static Properties class Ingredient { private grams:number; static gramsPerOunce:number = 28.35; getWeightInGrams():number { return this.grams; } } let butter = new Ingredient(); let ounces = butter.getWeightInGrams() * Ingredient.gramsPerOunce;

Slide 60

Slide 60 text

Classes - Static Properties function Ingredient() {} Ingredient.prototype.foo = function () {}; Ingredient.bar = function () {}; Ingredient.bar(); // static property

Slide 61

Slide 61 text

Functions function namedAdd(a:number, b:number): number { return a+b; } let anonymousAdd = function (a:number, b:number): number { return a+b; }; // reference parameter list return type definition let fullAdd: (a:number, b:number) => number = function (a:number, b:number): number { return a+b; };

Slide 62

Slide 62 text

Functions - Optionals & Defaults function incrementOptional(base:number, incrementBy?:number) { return base + incrementBy || 1; } function incrementDefaulted(base:number, incrementBy:number=1): number { return base + incrementBy; }

Slide 63

Slide 63 text

Functions - Variadic Parameters interface Ingredient {} interface IngredientList { ingredients:Ingredient[]; } function createIngredientList(...ingredients:Ingredient[]): IngredientList { let list = { ingredients:[] }; for (let ingredient of ingredients) { list.ingredients.push(ingredient); } return list; }

Slide 64

Slide 64 text

Functions - Overloading function cook(ingredients:IngredientList, cookingAppliance:any, ...options:Array): Meal { if (typeof cookingAppliance === "Skillet") { return new SkilletMeal(ingredients); } else if (typeof cookingAppliance === "Crockpot") { return new CrockpotMeal(ingredients, options[0], options[1]); } }

Slide 65

Slide 65 text

Functions - Overloading function cook(ingredients:IngredientList, crockpot:Crockpot, temp:number, time:number): CrockpotMeal; function cook(ingredients:IngredientList, skillet:Skillet): SkilletMeal; function cook(ingredients:IngredientList, cookingAppliance:any, ...options:Array): Meal { if (typeof cookingAppliance === "Skillet") { return new SkilletMeal(ingredients); } else if (typeof cookingAppliance === "Crockpot") { return new CrockpotMeal(ingredients, options[0], options[1]); } } let skillet = cook(new IngredientList(), new Skillet()); let crockpost = cook(new IngredientList(), new Crockpot(), 225, 360); let dutchoven = cook(new DutchOven()); > $ tsc examples/functions/overload.ts examples/functions/overload.ts(19,17): error TS2346: Supplied parameters do not match any signature of call target.

Slide 66

Slide 66 text

Lambdas let recipe = { ingredients: [ "flour", "water", "eggs", "butter" ], createWriter: function () { return function () { return this.ingredients.join("\n"); } } };

Slide 67

Slide 67 text

Lambdas let recipe = { ingredients: [ "flour", "water", "eggs", "butter" ], createWriter: function () { return () => { return this.ingredients.join("\n"); } } };

Slide 68

Slide 68 text

Lambdas var recipe = { ingredients: ["flour", "water", "eggs", "butter"], createWriter: function () { return function () { return this.ingredients.join("\n"); }; } }; var recipe = { ingredients: ["flour", "water", "eggs", "butter"], createWriter: function () { var _this = this; return function () { return _this.ingredients.join("\n"); }; } };

Slide 69

Slide 69 text

Generics • Allow flexibility in strictly typed systems • Allows type resolution at runtime through the use of generic components

Slide 70

Slide 70 text

Generics class Recipe { ingredients:Ingredient[]; add(ingredient:Ingredient) { this.ingredients.push(ingredient); } } class VeganRecipe extends Recipe { ingredients:VeganIngredient[]; add(ingredient:VeganIngredient) { this.ingredients.push(ingredient); } } let veganRecipe = new VeganRecipe(); veganRecipe.add(new VeganIngredient()); veganRecipe.add(new MeatIngredient()); // error

Slide 71

Slide 71 text

Generics class Recipe { ingredients:Ingredient[]; add(ingredient:Ingredient) { this.ingredients.push(ingredient); } } class VeganRecipe extends Recipe { ingredients:VeganIngredient[]; add(ingredient:VeganIngredient) { this.ingredients.push(ingredient); } } class MeatRecipe extends Recipe { ingredients:MeatIngredient[]; add(ingredient:MeatIngredient) { this.ingredients.push(ingredient); } } let meatRecipe = new MeatRecipe(); meatRecipe.add(new MeatIngredient()); let veganRecipe = new VeganRecipe(); veganRecipe.add(new VeganIngredient()); veganRecipe.add(new MeatIngredient()); // error

Slide 72

Slide 72 text

Generics class Recipe { ingredients:T[]; add(ingredient:T) { this.ingredients.push(ingredient); } } let meatRecipe = new Recipe(); meatRecipe.add(new MeatIngredient()); let veganRecipe = new Recipe(); veganRecipe.add(new VeganIngredient()); veganRecipe.add(new MeatIngredient()); // error

Slide 73

Slide 73 text

Generics class Recipe { ingredients:T[]; add(ingredient:T) { this.ingredients.push(ingredient); } } let badRecipe = new Recipe(); badRecipe.add(new BadIngredient()); > $ tsc examples/generics/generics.ts examples/generics/generics.ts(51,28): error TS2344: Type 'BadIngredient' does not satisfy the constraint 'Ingredient'.

Slide 74

Slide 74 text

Unions interface Chicken { boned:boolean; pluck(): void; fillet(): Meat; } interface Fish { boned:boolean; scale(): void; fillet(): Meat; } function fillet(animal:Chicken|Fish): Meat { return animal.fillet(); }

Slide 75

Slide 75 text

Unions function fillet(animal:Chicken|Fish): Meat { if (animal.pluck) { animal.pluck(); } if (animal.scale) { animal.scale(); } return animal.fillet(); } > $ tsc examples/unions.ts examples/unions.ts(13,16): error TS2339: Property 'pluck' does not exist on type 'Chicken | Fish'. examples/unions.ts(14,16): error TS2339: Property 'pluck' does not exist on type 'Chicken | Fish'. examples/unions.ts(16,16): error TS2339: Property 'scale' does not exist on type 'Chicken | Fish'. examples/unions.ts(17,16): error TS2339: Property 'scale' does not exist on type 'Chicken | Fish'.

Slide 76

Slide 76 text

Unions function fillet(animal:Chicken|Fish): Meat { if ((animal).pluck) { (animal).pluck(); } if ((animal).scale) { (animal).scale(); } return animal.fillet(); } \

Slide 77

Slide 77 text

Type Guards & Predicates function isChicken(animal:Chicken|Fish): animal is Chicken { return (animal).pluck !== undefined; } function isFish(animal:Chicken|Fish): animal is Fish { return (animal).scale !== undefined; } function fillet(animal:Chicken|Fish): Meat { if (isChicken(animal)) { animal.pluck(); } if (isFish(animal)) { animal.scale(); } return animal.fillet(); }

Slide 78

Slide 78 text

Intersections interface Meat { sourceAnimal:string } interface Game { gaminess:number } function prepareGameMeat(meat:Meat&Game): PreparedMeat { return new PreparedMeat(meat); }

Slide 79

Slide 79 text

Mixins interface Loggable { log(level:string, message:string): void } interface Serializable { serialize(): string } class ThingDoer implements Loggable, Serializable{ log(level:string, message:string):void { logTheThing(); } serialize():string { return "serialized ThingDoer!"; } } function doThing(thing:Loggable&Serializable): string { thing.log('info', 'Doing the thing!'); return thing.serialize(); }

Slide 80

Slide 80 text

Type Aliases type Unit = string; type UnitConverter = (Unit, value:number) => number; type WhiteMeat = Fish | Poultry; type Coords = [number,number,number]; type KosherMeat = "cattle" | "goat" | "sheep" | "chicken" | "duck" | "goose" type LinkedList = T & { next: LinkedList }; interface Ingredient { name:string; } var ingredients:LinkedList; ingredients.next.name; ingredients.next.next.name;

Slide 81

Slide 81 text

String Types // code copyright Microsoft 2012-2016 type Easing = "ease-in" | "ease-out" | "ease-in-out"; class UIElement { animate(dx: number, dy: number, easing: Easing) { if (easing === "ease-in") { // ... } else if (easing === "ease-out") { } else if (easing === "ease-in-out") { } else { // error! should not pass null or undefined. } } } let button = new UIElement(); button.animate(0, 0, "ease-in"); button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here

Slide 82

Slide 82 text

Modules export interface Meat {} export class Beef implements Meat {} export class Chicken implements Meat {} import * as meats from './meats'; let chicken = new meats.Chicken();

Slide 83

Slide 83 text

Namespaces namespace Meats { export interface Meat {} export class Beef implements Meat {} export class Chicken implements Meat {} } let chicken = new Meats.Chicken();

Slide 84

Slide 84 text

Declarations • Allow us to describe the shape of objects defined outside a TS app • https://github.com/typings/typings • https://github.com/typings/registry

Slide 85

Slide 85 text

Declarations // declaration for https://github.com/jonschlinkert/pad-left declare function padLeft (str: string, num: number, ch?: string): string; export = padLeft;

Slide 86

Slide 86 text

tsconfig.json • Configures compiler options • Presence indicates the root of a TypeScript project

Slide 87

Slide 87 text

tsconfig.json { "compilerOptions": { "module": "commonjs", "noImplicitAny": true, "removeComments": true, "preserveConstEnums": true, "outDir": "built/", "sourceMap": true }, "exclude": [ "node_modules" ] }

Slide 88

Slide 88 text

Thank you for listening! Rate speakers & the event! Questions? Samantha Quiñones @ieatkillerbees @squinones ɂ http://squinones.github.io ɔ https://joind.in/talk/bedf8