вторник, 29 июля 2014 г.

TypeScript Cheat Sheet

Primitive types
Any type (explicitly untyped)any
void type (null or undefined, use for function returns only)void
Stringstring
Numbernumber
Booleanboolean
Named types (interface, class, enum)
Interfaceinterface IChild extends IParent, SomeClass {
  property:Type;
  optionalProp?:Type;
  optionalMethod?(arg1:Type):ReturnType;
}
Classclass Child extends Parent implements IChild, IOtherChild {
  property:Type;
  defaultProperty:Type = 'default value';
  private _privateProperty:Type;
  static staticProperty:Type;
  constructor(arg1:Type) {
    super(arg1);
  }
  private _privateMethod():Type {}
  methodProperty:(arg1:Type) => ReturnType;
  overloadedMethod(arg1:Type):ReturnType;
  overloadedMethod(arg1:OtherType):ReturnType;
  overloadedMethod(arg1:CommonT):CommonReturnT {}
  static staticMethod():ReturnType {}
  subclassedMethod(arg1:Type):ReturnType {
    super.subclassedMethod(arg1);
  }
}
Enumenum Options {
  FIRST,
  EXPLICIT = 1,
  BOOLEAN = Options.FIRST | Options.EXPLICIT
}
Object type literals
Object with implicit Any properties{ foo; bar; }
Object with optional property{ required:Type; optional?:Type; }
Hash map{ [key:string]:Type; }
Arrays
Array of stringsstring[] or
Array<string>
Array of functions that return strings{ ():string; }[] or
Array<() => string>
Functions
Function{ (arg1:Type, argN:Type):Type; } or
(arg1:Type, argN:Type) => Type;
Constructor{ new ():ConstructedType; } or
new () => ConstructedType;
Function type with optional param(arg1:Type, optional?:Type) => ReturnType
Function type with rest param(arg1:Type, ...allOtherArgs:Type[]) => ReturnType
Function type with static property{ ():Type; staticProp:Type; }
Default argumentfunction fn(arg1:Type = 'default'):ReturnType {}
Arrow function(arg1:Type):ReturnType => {} or
(arg1:Type):ReturnType => Expression
Generics
Function using type parameters<T>(items:T[], callback:(item:T) => T):T[]
Interface with multiple typesinterface Pair<T1, T2> {
  first:T1;
  second:T2;
}
Constrained type parameter<T extends ConstrainedType>():T
Other
Type of a variabletypeof varName

---------------------------------------------------
Variable types
---------------------------------------------------

const - constant
i - integer
fl - float
s - string
b - boolean
a - array
f - function
o - object
c - class
m - module
$ - jQuery
_ - private

---------------------------------------------------
Comments
---------------------------------------------------

// Single line comment

/*
Multi
line
comment
*/

---------------------------------------------------
Basic Types
---------------------------------------------------

var isDone: boolean = false;           // Boolean
var height: number = 6;                 // Number
var name: string = "bob";               // String
var list:number[] = [1, 2, 3];          // Array - первый способ
var list:Array<number> = [1, 2, 3]; // Array - второйспособ
var notSure: any = 4;                    // Any
enum Color {Red, Green, Blue};      // Enum
var c: Color = Color.Green;
function warnUser(): void {alert("This is my warning message");} // Void

---------------------------------------------------
Anonymously-typed var
---------------------------------------------------

declare var MyPoint: { x: number; y: number; };

---------------------------------------------------
Interfaces
---------------------------------------------------

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

var myObj = {size: 10, label: "Size 10 Object"};

printLabel(myObj);

---------------------------------------------------
Implementing an interface
---------------------------------------------------

interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface  {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

---------------------------------------------------
Extending Interfaces
---------------------------------------------------

interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface Square extends Shape, PenStroke {
    sideLength: number;
}

var square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

---------------------------------------------------
Class
---------------------------------------------------

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

var greeter = new Greeter("world");

---------------------------------------------------
Class Inheritance
---------------------------------------------------

class Animal {
    name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move() {
        alert("Galloping...");
        super.move(45);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

---------------------------------------------------
Private modifier
---------------------------------------------------

class Animal {
    private name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number) {
        alert(this.name + " moved " + meters + "m.");
    }
}

---------------------------------------------------
Get/Set Accessors
---------------------------------------------------

var passcode = "secret passcode";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

    set fullName(newName: string) {
        if (passcode && passcode == "secret passcode") {
            this._fullName = newName;
        }
        else {
            alert("Error: Unauthorized update of employee!");
        }
    }
}

var employee = new Employee();
employee.fullName = "Bob Smith";

if (employee.fullName) {
    alert(employee.fullName);
}

---------------------------------------------------
Static Properties
---------------------------------------------------

class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        var xDist = (point.x - Grid.origin.x);
        var yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

var grid1 = new Grid(1.0);  // 1x scale
var grid2 = new Grid(5.0);  // 5x scale

alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

---------------------------------------------------
Modules
---------------------------------------------------

module Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    var lettersRegexp = /^[A-Za-z]+$/;
    var numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}

// Some samples to try
var strings = ['Hello', '98052', '101'];

// Validators to use
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();

// Show whether each string passed each validator
strings.forEach(s => {
    for (var name in validators) {
        console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
    }
});

---------------------------------------------------
Module Import
---------------------------------------------------

import someMod = require('someModule');
import validation = require('./Validation');

---------------------------------------------------
Module Alias
---------------------------------------------------

module Shapes {
    export module Polygons {
        export class Triangle { }
        export class Square { }
    }
}

import polygons = Shapes.Polygons;
var sq = new polygons.Square(); // Same as 'new Shapes.Polygons.Square()'

---------------------------------------------------
Functions
---------------------------------------------------

// Named function
function add(x: number, y: number): number {
    return x+y;
}

// Anonymous function
var myAdd = function(x: number, y: number): number { return x+y; };

var myAdd: (baseValue:number, increment:number)=>number = function(x: number, y: number): number { return x+y; };

---------------------------------------------------
Default Parameters
---------------------------------------------------

function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

var result1 = buildName("Bob");  //works correctly now, also
var result2 = buildName("Bob", "Adams", "Sr.");  //error, too many parameters
var result3 = buildName("Bob", "Adams");  //ah, just right

---------------------------------------------------
Optional Parameters
---------------------------------------------------

function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + " " + lastName;
    } else {
        return firstName;
    }
}

var result1 = buildName("Bob");  //works correctly now
var result2 = buildName("Bob", "Adams", "Sr.");  //error, too many parameters
var result3 = buildName("Bob", "Adams");  //ah, just right

---------------------------------------------------
Rest Parameters
---------------------------------------------------

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

var employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

The ellipsis (...) is also used in the type of the function with rest parameters:

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}

var buildNameFun: (fname: string, ...rest: string[])=>string = buildName;

---------------------------------------------------
Overloads
---------------------------------------------------

JavaScript is inherently a very dynamic language. It's not uncommon for a single JavaScript function to return different types of objects based on the shape of the arguments passed in.

var suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x): any {
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        var pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        var pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

var myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
var pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

var pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

---------------------------------------------------
Generics
---------------------------------------------------

The "identity" function is a function that will return back whatever is passed in.

function identity(arg: any): any {
    return arg;
}

While using 'any' is certainly generic in that will accept any and all types for the type of 'arg', we actually are losing the information about what that type was when the function returns.
If we passed in a number, the only information we have is that any type could be returned.

Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned.
Here, we will use a type variable, a special kind of variable that works on types rather than values.

function identity<T>(arg: T): T {
    return arg;
}

This 'T' allows us to capture the type the user provides (eg, number), so that we can use that information later.
Here, we use 'T' again as the return type.

Once we've written the generic identity function, we can call it in one of two ways.
The first way is to pass all of the arguments, including the type argument, to the function:

var output = identity<string>("myString");  // type of output will be 'string'

The second way is also perhaps the most common.
Here we use /type argument inference/, that is, we want the compiler to set the value of T for us automatically based on the type of the argument we pass in:

var output = identity("myString");  // type of output will be 'string'

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no error
    return arg;
}

We can alternatively write the sample example this way:

function loggingIdentity<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);  // Array has a .length, so no error
    return arg;
}

---------------------------------------------------
Generic Classes
---------------------------------------------------

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

var myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

---------------------------------------------------
Mixins
---------------------------------------------------

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {
        this.isDisposed = true;
    }

}

// Activatable Mixin
class Activatable {
    isActive: boolean;
    activate() {
        this.isActive = true;
    }
    deactivate() {
        this.isActive = false;
    }
}

class SmartObject implements Disposable, Activatable {
    constructor() {
        setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
    }

    interact() {
        this.activate();
    }

    // Disposable
    isDisposed: boolean = false;
    dispose: () => void;
    // Activatable
    isActive: boolean = false;
    activate: () => void;
    deactivate: () => void;
}

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    });
}

applyMixins(SmartObject, [Disposable, Activatable])

var smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000);

---------------------------------------------------
Merging Interfaces
---------------------------------------------------

interface Box {
    height: number;
    width: number;
}

interface Box {
    scale: number;
}

var box: Box = {height: 5, width: 6, scale: 10};

---------------------------------------------------
Merging Modules
---------------------------------------------------

module Animals {
    export class Zebra { }
}

module Animals {
    export interface Legged { numberOfLegs: number; }
    export class Dog { }
}

---------------------------------------------------
Common Errors
---------------------------------------------------

window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.buton);  //<- Error
};

window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.buton);  //<- Now, no error is given
};

---------------------------------------------------
Class Decomposition
---------------------------------------------------

// Standard

class A {
    static st: string;
    inst: number;
    constructor(m: any) {}
}

// Decomposed class

interface A_Static {
    new(m: any): A_Instance;
    st: string;
}

interface A_Instance {
    inst: number;
}

declare var A: A_Static;

Комментариев нет:

Отправить комментарий