레이블이 typescript인 게시물을 표시합니다. 모든 게시물 표시
레이블이 typescript인 게시물을 표시합니다. 모든 게시물 표시

2014년 6월 15일 일요일

TypeScript 문법 특징 (Modules, Functions, Generics)

JavaScript 문법이나 자세한 내부적인 동작들을 알고 TypeScript 문법을 보면 비교를 해보면서 좋겠지만.. 일단 guide 그대로 보고 정리함.
(원문) http://www.typescriptlang.org/Handbook

[Modules]

module 내부에서 정의된 methods들을 외부에서 사용하려면 export keyword를 사용해야 함.

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);
    }
});

[Multi-file internal modules]

독립된 파일을 export해서 사용하는 방법.
/// <reference path="xxxx.ts" /> 를 명시하여 다른 파일에 존재하지만 컴파일러에서는 한 파일로 구성된것으로 취급

Validation.ts
module Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}
LettersOnlyValidator.ts
/// <reference path="Validation.ts" />
module Validation {
    var lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}
ZipCodeValidator.ts
/// <reference path="Validation.ts" />
module Validation {
    var numberRegexp = /^[0-9]+$/;
    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}
Test.ts
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />

// 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);
    }
});

컴파일할 때는 파일들을 컴파일 해서 하나의 JavaScript 파일(--out sample.js)로 만들거나
tsc --out sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts
각각의 파일들을 컴파일 해서 모든 JavaScript 결과물들을 명시하는 방법이 있다.
    <script src="Validation.js" type="text/javascript" />
    <script src="LettersOnlyValidator.js" type="text/javascript" />
    <script src="ZipCodeValidator.js" type="text/javascript" />
    <script src="Test.js" type="text/javascript" />

[Going External]

위의 reference tag를 사용하지 않고 아래 import를 사용하는 방법이 있음.

import someMod = require('someModule');

컴파일 시 import 구문을 확인하여 관련 파일들을 컴파일하게 된다.
다만 컴파일 시 --module flag를 지정하여 external module target을 알려줘야 한다. (자세한 개념은 모르겠으니 아래 링크를 참고
- JavaScript 표준을 위한 움직임: CommonJS와 AMD [http://helloworld.naver.com/helloworld/12864] )

tsc --module commonjs Test.ts

Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import validation = require('./Validation');
var lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
ZipCodeValidator.ts
import validation = require('./Validation');
var numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
Test.ts
import validation = require('./Validation');
import zip = require('./ZipCodeValidator');
import letters = require('./LettersOnlyValidator');

// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: validation.StringValidator; } = {};
validators['ZIP code'] = new zip.ZipCodeValidator();
validators['Letters only'] = new letters.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);
    }
});

** 흠.. 모르겠다.. 일단.. 생략..

[Functions]

일반적인 TypeScript에서의 function definition이다.

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

[Inferring the types]

첫번째에서는 function parameter의 type을 지정했지만 두번째 에서는 x, y의 type을 지정하지 않았지만 TypeScript compiler에서는 number로 유추하여 처리한다고 함.

// myAdd has the full function type
var myAdd = function(x: number, y: number): number { return x+y; };

// The parameters 'x' and 'y' have the type number
var myAdd: (baseValue:number, increment:number)=>number = 
    function(x, y) { return x+y; };

[Optional and Default Parameters]

JavaScript와 다르게 TypeScript에서는 function의 parameter의 수가 맞아야 한다.

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

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

Parameter를 optional로 처리하기 위해서는 다음과 같이 '?'를 붙여주면 됨.

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

아니면 default value를 지정해 주어 처리할 수 도 있음.

unction 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

[Rest Parameters]

reset parameter 명칭이 맞는지 모르겠지만 몇개의 parameter가 들어올 지 모르는 함수의 경우 C 같은 곳에서 '...'로 지정해 놓는 것과 같은 문법을 TypeScript에서 지원한다.

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

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

JavaScript에서는 아래와 같이 처리할 수 있음.

https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-8/function-arguments-and
function max(/* ... */) {
    var max = Number.NEGATIVE_INFINITY;
    // Loop through the arguments, looking for, and remembering, the biggest.
    for(var i = 0; i < arguments.length; i++)
        if (arguments[i] > max) max = arguments[i];
    // Return the biggest
    return max; 
}

var largest = max(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6);  // => 10000
[Lambdas and using 'this']

JavaScript에서 this 사용은 강력하고 유연한 객체 접근을 도와주지만 호출 시 올바른 객체에 접근할 수 있어야 하므로 cost가 발생된다.
아래의 예제에서 cardPicker()를 호출할 경우 deck.createCardPicker()내의 this는 deck를 가리키는게 아니라 Window 개체를 가리키게 되어 정상적으로 동작되지 않는다.

var deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        return function() {
            var pickedCard = Math.floor(Math.random() * 52);
            var pickedSuit = Math.floor(pickedCard / 13);
   
            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

var cardPicker = deck.createCardPicker();
var pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

다른 방법으로 수정할 수 있으나 (아래 링크 참조) lambda 문법을 사용해서 생성되었을 때의 this를 capture할 수 있다.

Understanding JavaScript Function Invocation and “this”
: http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/
JavaScript를 제대로 몰라서 위의 방법을 몰라 눈가리고 아웅식으로 전역처리해서 넘어갔었는데.. 부끄럽다..

var deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        // Notice: the line below is now a lambda, allowing us to capture 'this' earlier
        return () => {
            var pickedCard = Math.floor(Math.random() * 52);
            var pickedSuit = Math.floor(pickedCard / 13);
   
            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

var cardPicker = deck.createCardPicker();
var pickedCard = cardPicker();

alert("card: " + pickedCard.card + " of " + pickedCard.suit);

[Overloads]

... 나중에..



[Generics]


Generic을 사용하는 이유 중 하나는 데이터형에 상관없이 유연한 재사용 가능한 코드를 만드는 것이겠고 그것을 Type script에서는 지원한다.

기본적으로 아래 코드르
function identity(arg: number): number {
    return arg;
}
모든 type을 받고 제공할 수 있도록 고칠 수 있고
function identity(arg: any): any {
    return arg;
}
좀 더 나아가서 함수에서 사용하는 data type을 아래와 같이 선언해 줄 수 있음.
function identity<T>(arg: T): T {
    return arg;
}
위 Generic 함수를 사용하는 방법은 아래와 같이 explicit, implicit 하게 쓸 수 있음.

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

var output = identity("myString");  // type of output will be 'string'
코드의 간결함을 위해 implicit하게 사용할 수 있으며 이때 compiler는 argument type을 기반하여 generic type을 유추한다.


[Working with Generic Type Variables]

T type의 array을 argument로 사용하려면 두번째 예제 처럼 해당 type을 T의 array type으로 특수화 해야 함.

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

[Generic Types]

기존 function prototype ( argument :  type ) => return 앞에 generic type <T>만 붙여
Generic typed function을 type의 varaialbe을 선언하는 방법과

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

var myIdentity: <T>(arg: T)=>T = identity;
object literal type으로 지정해서 사용할 수 있음.
function identity<T>(arg: T): T {
    return arg;
}

var myIdentity: {<T>(arg: T): T} = identity;
interface를 지정해서 사용하는 방법도 있다.
하지만 interface의 generic type이 명시적으로 선언되어 있지 않아 모호한 상황이 발생할 수도 있겠다.
interface GenericIdentityFn {
    <T>(arg: T): T;
}

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

var myIdentity: GenericIdentityFn = identity;
interface도 generic type으로 선언해서 interface 사용 시 명시적으로 generic type을 지정하도록 하는게 바람직 할 듯.
interface GenericIdentityFn<T> {
    (arg: T): T;
}

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

var myIdentity: GenericIdentityFn<number> = identity;

[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; };
var stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };

alert(stringNumeric.add(stringNumeric.zeroValue, "test"));
어떤 class type parameter를 선언해서 GenericNumber class를 사용해도 상관이 없으나 static member에는 class type parameter를 사용하지 못한다.

[Generic Constraints]

Generic type의 member method를 제한하고 싶을 경우 interface를 사용하여 제어할 수 있음.

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}
아래와같이 interface를 맞춰 주면 ok
loggingIdentity({length: 10, value: 3});  

[Using Type parameters in Generic Constraints]

.. 나중에

function find<T, U extends Findable<T>>(n: T, s: U) {   // errors because type parameter used in constraint
  // ...
} 
find (giraffe, myAnimals);

function find<T>(n: T, s: Findable<T>) {   // errors because type parameter used in constraint
  // ...
} 
find(giraffe, myAnimals);


[Using Class Types in Generics]

.. 나중에

function create<T>(c: {new(): T; }): T { 
    return new c();
}


class BeeKeeper {
    hasMask: boolean;
}

class ZooKeeper {
    nametag: string; 
}

class Animal {
    numLegs: number;
}

class Bee extends Animal {
    keeper: BeeKeeper;
}

class Lion extends Animal {
    keeper: ZooKeeper;
}

function findKeeper<A extends Animal, K> (a: {new(): A; 
    prototype: {keeper: K}}): K {

    return null;
}

findKeeper(Lion).nametag;  // works!
















2014년 6월 1일 일요일

TypeScript 문법 특징 (Basic types, Interfaces, Classes)

JavaScript 문법이나 자세한 내부적인 동작들을 알고 TypeScript 문법을 보면 비교를 해보면서 좋겠지만.. 일단 guide 그대로 보고 정리함.

(원문) http://www.typescriptlang.org/Handbook


[Basic Types]

변수 마다 명시적 type 지정을 한다.

var isDone: boolean = false;

array도 마찬가지이고 generic 선언 형식도 지원한다.

var list:number[] = [1, 2, 3];
var list:Array<number> = [1, 2, 3];

enum type도 지원

enum Color {Red = 1, Green, Blue};
var c: Color = Color.Green;
enum Color {Red = 1, Green, Blue};
var colorName: string = Color[2];

alert(colorName);

Any는 뭐 기본이니 TypeScript에서 배열에 이것저것 넣을 때 유용할 거 같다.

var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
var list:any[] = [1, true, "free"];

list[1] = 100;

void도 있음.

function warnUser(): void {
    alert("This is my warning message");
}


[Interfaces]

기본적인 interface 문법이다.class 선언하듯 property를 정해서 interface로 선언하고 사용하면 된다.

interface LabelledValue {
  label: string;
}

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

var myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
그리고 interface를 사용하되 property 속성을 '?' keyword를 사용하여 optional로 처리 하여 사용하는 class가 사용하지 않게 할 수 있음.

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  var newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

var mySquare = createSquare({color: "black"});
type checking 상황에서 Interface를 사용하게 될 경우 실수로 인한 오타의 경우 (ex config.collor) 확인가능하다. 일반적인 javascript 상황에서는 config의 속성으로 인지하고 null값의 변수로 처리되는것에 반해...


[Function Types]

function을 정의하는데 interface를 사용한다....
좀 이상하긴 한데.. 굳이 보자면 static function 정도로 봐야 할까?

interface SearchFunc {
  (source: string, subString: string): boolean;
}

var mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  var result = source.search(subString);
  if (result == -1) {
    return false;
  }
  else {
    return true;
  }
}


[Array Types]

Array도 interface를 사용해서 선언 할 수 있음.
다만 index는 number, string만 가능하다.

interface StringArray {
  [index: number]: string;
}

var myArray: StringArray;
myArray = ["Bob", "Fred"];

이건 뭐...?
interface Dictionary {
  [index: string]: string;
  length: number;    // error, the type of 'length' is not a subtype of the indexer
} 


[Class Types]

Interface를 선언하고 그것을 implements 해서 class를 선언

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface  {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

class와 interface를 사용할 때 static side, instance side의 개념을 이해해야 함.
아래 예제의 interface에서 선언된 constructor(new)는 static side에서 선언되어 있어 class의 instance side에서 new가 선언되어 있지 않는 것으로 판단되어 에러로 처리된다.

interface ClockInterface {
    new (hour: number, minute: number);
}

class Clock implements ClockInterface  {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
그래서 아래와 같이 interface를 구현하지 말고 class 선언 하고 interface type으로 interface의 instance(엄밀히보면 아닐 듯)를 만들고 다시 instance를 생성자를 호출해서 만들며 초기화 한다..(맞나??)
좀 복잡하다.. 사실 상 interface로 생성자를 명시할 필요는 있겠지만.. 생각보다 복잡하네..

interface ClockStatic {
    new (hour: number, minute: number);
}

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

var cs: ClockStatic = Clock;
var newClock = new cs(7, 30);


[Extending Interfaces]

interface 간 상속이 가능하다. 다중상속도 가능하다.

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

var square: Square;
square.color = "blue";
square.sideLength = 10;


[Hybrid Types]

위에서 언급함 interface의 속성들이 함께 사용 될 수 있음.

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

var c: Counter;
c(10);
c.reset();
c.interval = 5.0;

[Classes]

간단한 class 예제

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

var greeter = new Greeter("world");

아래는 컴파일 된 JavaScript 결과물임.

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

var greeter = new Greeter("world");



[Inheritance]

아래에서 sam은 type을 선언하지 않고 바로 Snake의 instance를 생성하고 tom은 Animal type으로 Horse의 instance를 생성했음. 결과적으로는 각 class들(Snake, Horse)에서 override한 move()이 호출 된다.
JavaScript의 속성상 move()의 prototype이 다르더라도 Animal의 move()가 각 class에서 override 되어 tom의 type이 Animal이라도 instance에서 override된 move()가 호출 되었음.

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/Public modifiers]

기본적으로 class내의 properties, methods들은 public 속성을 가지고 private으로 선언하고자 할 경우 모든 variables, methods에 명시적으로 private을 선언해야 한다.


[Parameter properties]

private 키워드를 생성자의 argument에 선언하면 실제 class의 property를 argument로 초기화 한다는 얘기, public property도 마찬가지.

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

[Accessors]

setter, getter를 위해 set, get 지시자를 사용하면 된다.
다만 compiler output을 ECMAScript 5로 설정해야지 사용 가능하다고 함.

ar 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]

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}));

[Constructor functions]

좀 이상한 예제긴 하지만 greeterMaker에 Greeter 원형을 대입해서 static property를 수정할 수 있는 것을 볼 수 있음.

class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}

var greeter1: Greeter;
greeter1 = new Greeter();
alert(greeter1.greet());

var greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!";
var greeter2:Greeter = new greeterMaker();
alert(greeter2.greet());

[Using a class as an interface]

class도 interface로 사용할 수 있음.. 근대 왜?

class Point {
    x: number;
    y: number;
}

interface Point3d extends Point {
    z: number;
}

var point3d: Point3d = {x: 1, y: 2, z: 3};

2014년 5월 29일 목요일

TypeScript 특징

HTML5 Game Engine을 조사하던 차에 Turbulenz라는 곳에서
TypeScript를 사용해서 엔진을 개발했다고 해서 한번 찾아보게 되었음.
TypeScript는 Microsoft에서 개발 되어 공개되었고 type checking이 추가된 JavaScript의 superset이라 기존 JavaScript에 익숙하면 전이하기는 쉽고 TypeScript를 컴파일?한 결과물은 Javascript이므로 기존 Browser가 변경될 필요가 없다는게 특징이다.
OOP 개념을 가진 JavaScript 초보들에게는 좋을 수도....

다만 JavaScript의 subset이어서 기본 JavaScript library들을 사용하고자 할 경우 별도의 definition이 필요하다..

아래는 MS에서 공개한 TypeScript의 resource들이며
그 중 Tutorial을 먼저 보되 Simple Guide를 함께 보는게 편하겠음.
Specification은 120페이지라 필요할 때 보면 되고....


TypeScript
 : http://www.typescriptlang.org/
 : http://typescript.codeplex.com/

Simple Guide : http://www.typescriptlang.org/Handbook
Tutorial : http://www.typescriptlang.org/Tutorial
Language specification : http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

: TypeScript sample code

class Student {
    fullname : string;
    constructor(public firstname, public middleinitial, public lastname) {
        this.fullname = firstname + " " + middleinitial + " " + lastname;
    }
}

interface Person {
    firstname: string;
    lastname: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstname + " " + person.lastname;
}

var user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

[Type Script 특징]

보다보니 Simple Guide 중에서 아래와 같은 문구가 있음.

One of TypeScript's core principles is that type-checking focuses on the 'shape' that values have. This is sometimes called "duck typing" or "structural subtyping". In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project. 

TypeScript의 기본 원칙들 중 하나가 변수가 가진 값의 형태에 따라 type-checking을 하는 것이고 이를 duck typing, structural subtyping이라고 한다. 라고 하고 있어 근본적으로 JavaScript와 다른 점을 알 수 있음.


[TypeScript: First Impressions]
: http://tirania.org/blog/archive/2012/Oct-01.html

위에서 Miguel de Icaza께서 TypeScript에 대해서 정리한 글임. pros, cons를 통해서 특징을 살펴 볼 수 있음.
간단히 보면 쉽게 배울 수 있고 type checking으로 통한 장점을 수용할 수 있고 컴파일 결과물은 JavaScript 코드 이므로 기존 browser나 runtime을 변경할 필요가 없음. 다만 개발환경이 VisualStudio에 국한된 것은 단점 임.

 - Pros
  : Javascript의 superset으로 기존 쉽게 전이할 수 있음.
  : Apache License로 Open Source
  : Code deploy전 type assist와 error 확인이 가능
  : Extensive type inference을 통해 type checking의 장점과 함께 JavaScript의 dynamism의 지킬 수 있음.
  : Classes, interfaces의 사용과 visibility 향상
  : explicit construct의 사용의 장점 (장점을 Nice syntactic sugar reduces boilerplate code 라 표현함)
  : TypeScript는 Node.JS pacakage로서 배포되므로 Linux, MacOS에서도 설치 가능
  : TypeScript는 compile time이나 server side에 적용되므로 code 실행을 위해 기존 browser나 runtime이 수정될 필요는 없음.

 - Cons
  : 사실상 Web은 Unix 기반이다.
  : 대부분 개발자들은 MacOS, Linux 상에서 code를 작성하고 Linux server로 deploy한다.
    그러므로 위에서 말한 type checking의 장점 주는 적절한 tool은 현재 Visual Studio Professional만 존재하므로 Windows외 환경에서는 이점을 누릴 수 없음.


그외 Google Dart team member가 작성한 자세한 정리글이 있는데 reddit은 너무 보기 지겹다.. ㅜㅜ
http://www.reddit.com/r/programming/comments/10rkd9/welcome_to_typescript/

그리고 TypeScript introduction video의 답글을 보면 꽤나 부정적임.. ㅎㅎㅎ
http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript


[TypeScript개발을 위해 필요한 것들]

[Compiler]

Visual Studio 2012용 설치 파일이 있어 설치하면 editor, compiler가 설치된다.
그외에는 Node.js package maanger를 통해서 설치할 수 있다고 하는데 안해봤음.

그리고 Visual Studio 2013 Update 2가 설치되어 있다면 기본으로 깔려 있으나
재미있는건 Visual Studio 2013 Update 2가 아니라면
아래 링크의 TypeScript 1.0 Tools를 설치해도 VS2013에서는 메뉴가 나타나지 않는다.

TypeScript 1.0 Tools for Visual Studio 2012
: http://visualstudiogallery.msdn.microsoft.com/fa041d2d-5d77-494b-b0ba-8b4550792b4d
: http://www.microsoft.com/en-us/download/details.aspx?id=34790

[Editors]
- Visual Studio 2012, 2013
- Vi, Emacs
 : http://msopentech.com/blog/2012/10/01/sublime-text-vi-emacs-typescript-enabled/