01.Typescript - nkiateam/angular-tutorial GitHub Wiki

TypeScript ์†Œ๊ฐœ

JavaScript that scales.

TypeScript๋Š” 2012๋…„ 10์›”์— Microsoft์—์„œ ๋ฐœํ‘œํ•˜์˜€๋‹ค.
ES2015์„ ๊ธฐ๋ฐ˜์œผ๋กœํ•œ OOPํ˜•ํƒœ์˜ ์ •์  ํƒ€์ดํ•‘ ์–ธ์–ด์ด๋ฉฐ, JavaScript๋กœ ์ปดํŒŒ์ผ ๋œ๋‹ค.
๋Œ€๊ทœ๋ชจ Application ๊ฐœ๋ฐœ์‹œ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋†’์€ ์ž์œ ๋„(๋™์  ํƒ€์ดํ•‘)์— ์˜ํ•ด์„œ ๋ฐœ์ƒ๋˜๋Š” ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ ์„ ์ฐพ๊ณ ์ž ๊ฐœ๋ฐœํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
๋‚˜์˜ฌ ๋‹น์‹œ์—๋Š” Windows ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์ง€์›์ด ๋ฏธ๋น„ํ•ด์„œ ๋ถ€์ •์ ์ธ ์˜๊ฒฌ๋„ ์ ์ง€ ์•Š์•˜๋˜ ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ์ง€๋งŒ,
์ƒํƒœ๊ณ„ ์ง€์›์ด ์ ์  ํ™•์žฅ๋˜๊ณ , ์ตœ๊ทผ์—๋Š” Angular ํŒ€์—์„œ ์ด ์–ธ์–ด๋ฅผ ๋ฉ”์ธ ์–ธ์–ด๋กœ ์ฑ„ํƒํ•˜๋ฉด์„œ ํ˜„์žฌ๋กœ์„œ๋Š” ์ •์  ํƒ€์ดํ•‘์„ ์ง€์›ํ•˜๋Š” ๋‹ค๋ฅธ JavaScript ์ „์ฒ˜๋ฆฌ๊ธฐ(Flow ๋“ฑ)์— ๋น„ํ•ด์„œ ์ปค๋ฎค๋‹ˆํ‹ฐ๋‚˜ ์•ˆ์ •์„ฑ ์ธก๋ฉด์—์„œ ์•ž์„œ๋‚˜๊ฐ€๋Š” ๋ชจ์–‘์ƒˆ๋‹ค.
๊ธฐ์กด IDE์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์›ํ• ํžˆ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ์ ๋„ ํ•ด๊ฒฐํ•˜๊ธฐ ํ•˜๊ณ ์ž ํ˜„์žฌ๋Š” Visual Studio, Sublime Text2๋“ฑ์˜ IDE์—์„œ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €, ๋ชจ๋“  ํ˜ธ์ŠคํŠธ, ๋ชจ๋“  OS๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.

TypeScript๋Š” ์ผ๋ฐ˜์ ์ธ JavaScript๋กœ ์ปดํŒŒ์ผ๋˜๋Š” ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ์˜ Superset์ด๋‹ค.
์ฆ‰, ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ–ˆ๋˜ ์ต์ˆ™ํ•œ JavaScript์˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ์ฝ”๋”ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
ํŠนํžˆ, TypeScript๋Š” ES2015 ๋ฌธ๋ฒ•๋„ ์ง€์›ํ•˜๋ฏ€๋กœ TypeScript ์ด์™ธ์˜ ๋ณ„๋„ Transpiler๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ES2015 ๊ธฐ๋Šฅ๋“ค์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ๋‹ค.
๊ฒŒ๋‹ค๊ฐ€ ๋ฏธ๋ž˜์˜ ECMAScript Feature๋“ค๋„ ๊ณ„์†ํ•ด์„œ ์ง€์›ํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ ํ‘œ์ค€์—์„œ ๋ฒ—์–ด๋‚  ๊ฑฑ์ •๋„ ๋œ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

Javascript ๋ฌธ์ œ์ 

  • ์ฝ”๋”ฉ์ค‘ ๋ฐœ์ƒ๋˜๋Š” ์˜ค๋ฅ˜
var number = "๋ฌธ์ž์—ด";
var str = number - 10; // ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ๋˜์ง€ ์•Š์Œ.
typeof str?  ๋ฌธ์ž์ผ๊นŒ์š” ์ˆซ์ž์ผ๊นŒ์š”......

'' == false	// true
undefined == null // true
false == null // false

var one = 1;
var oneString = "1";
if(one == oneString){
    alert("์„œ๋กœ ๊ฐ™๋‹ค.");
}
  • ์ƒ์†์˜ ๋ฌธ์ œ์  - ๋ณต์žก๋„
function Car(){ /* code.... */ }
function Truck = function(){
	// consructor chain
	Car.apply(this, arguments);
	/* Some code ... */
}
Truck.prototype = new Car();
var porter = new Truck();
  • ๋ถ€์‹คํ•œ IDE
    • Code Assist
    • Syntax Warning
    • Code Tracking ๋ถˆ๊ฐ€
    • Code Refactoring ๋ถˆ๊ฐ€

Angular๋Š” ์™œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

Angular 1.x ๋ฒ„์ „์—์„œ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ์‹œ์— object๋‚˜ method์— ๋Œ€ํ•œ ์ ˆ์ฐจ๊ฐ€ ํ‹€๋ฆฐ ๊ฒฝ์šฐ๋‚˜ ํ˜•๋ณ€ํ™˜ ๋ฌธ์ œ์  ๋“ฑ์ด
runtime์‹œ์—๋งŒ ๋ฐœ๊ฒฌ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์œผ๋ฉฐ, ์œ„์˜ ์‚ฌํ•ญ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์— ๋ณด๋‹ค ๋งŽ์€ ์ฝ”๋“œ์™€ ์‹œ๊ฐ„์„ ๋“ค์—ฌ์„œ ์ž‘์„ฑํ•˜์˜€์ง€๋งŒ,
์—ฌ์ „ํžˆ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒ๋˜์—ˆ๋‹ค.
๊ทธ๋ž˜์„œ Angular๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋„์ž…ํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , ์ •์  ํƒ€์ดํ•‘์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ ์ปดํŒŒ์ผ์‹œ์— ์ž˜๋ชป ์„ ์–ธ๋œ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ๋ฏธ์—ฐ์— ๋ฐฉ์ง€ํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํŠน์ง•

  • Type annotations
    Type annotaion์€ function์ด๋‚˜ ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์ˆ ํ•˜๋Š” ๋ถ€๋ถ„์„ ๋‹ด๋‹นํ•œ๋‹ค.
// ๋ณ€์ˆ˜์ •์˜
const name: string = 'NKIA';

// ํ•จ์ˆ˜์ •์˜
function echo(param: string): string {
  return param;
}

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

// ํƒ€์ž…๊ณผ ๋ณ€์ˆ˜์— ํ• ๋‹น๊ฐ’์ด ๋งž์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์˜ ์—๋Ÿฌ ์˜ˆ์‹œ. => ์ปดํŒŒ์ผ์‹œ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜ ๋ฐœ์ƒ๊ฐ€ ๋ณด์—ฌ์ง€๋ฉฐ, ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š”๋‹ค.
error TS2322: Type 'string' is not assignable to type 'number'

  • Interfaces
    ์ž๋ฐ”์˜ interface์™€ ์œ ์‚ฌํ•œ ๊ฐœ๋…์ด๋ฉฐ, ๋ณ€์ˆ˜์™€ method์˜ ์„ ์–ธ๋ถ€๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
    ์‹ค์ œ ๊ตฌํ˜„์€ implements ํ‚ค์›Œ๋“œ๋กœ ๊ตฌํ˜„๋ถ€๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
interface Shape {
  getArea(): number;
}

class Rect implements Shape {
  width : number;
  height: number;
  constructor(width, height) {
    this.width  = width;
    this.height = height;
  }
  // Method ๊ตฌํ˜„๋ถ€, ๊ตฌํ˜„๋ถ€๊ฐ€ ์—†์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  // error: Class 'Rect' incorrectly implements interface 'Shape'. Property 'getArea' is missing in type 'Rect'.
  getArea(){
    return 1;
  }
}

// interface ๊ฐ„ ์ƒ์† ์ง€์›. ๋‹ค์ค‘์ƒ์†๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

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

// optional ํ‘œํ˜„ ? ์‚ฌ์šฉ. class์—์„œ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
interface SquareConfig {
  color?: string;
  width?: number;
}

// Javascript ์ฝ”๋“œ
class Duck {
  quack() {
    console.log('๊ฝฅ!');
  }
}
class Person {
  /* ๊ตฌํ˜„์ด ์•ˆ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ..
  quack() {
    console.log('๋‚˜๋„ ๊ฝฅ!');
  }
  */
}
function makeSomeNoiseWith(duck) {
  duck.quack();
}
makeSomeNoiseWith(new Duck()); // OK
makeSomeNoiseWith(new Person()); // OK

-- error: quack() is not a function. ์—๋Ÿฌ๊ฐ€ Runtime์‹œ์— ๋ฐœ์ƒํ•˜๋Š” ๋ถˆ์ƒ์‚ฌ....
// TypeScript ์ฝ”๋“œ
interface Quackable {
  quack(): void;
}
class Duck implements Quackable {
  quack() {
    console.log('๊ฝฅ!');
  }
}
class Person {
  /*
  quack() {
    console.log('๋‚˜๋„ ๊ฝฅ!');
  }
  */
}
function makeSomeNoiseWith(duck: Quackable): void {
  duck.quack();
}
makeSomeNoiseWith(new Duck()); // OK
makeSomeNoiseWith(new Person()); // OK

-- Quackable์˜ Person ๊ฐ์ฒด์— quack()๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„ ์ปดํŒŒ์ผ์‹œ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  • Classes
    es2015 ๊ธฐ๋ฐ˜์˜ class ์ง€์›, ๋ชจ๋“ˆํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•œ๋‹ค.
    ์ ‘๊ทผ ์ œํ•œ์ž, static, getter, setter ๋“ฑ์„ ์ง€์›ํ•œ๋‹ค.
// ๊ธฐ๋ณธ๋ฌธ๋ฒ•
class Cat {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age  = age;
  }
  gatName(){
      return this.name;
  }
}

// ์ปดํŒŒ์ผ๋œ Javascript ์ฝ”๋“œ
var Cat = (function(){
    function Cat(name, age){
        this.name = name;
        this.age = age;
    }
    Cat.prototype.getName = function(){
        return this.name;
    };
    return Cat;
})();


// ์ ‘๊ทผ ์ œํ•œ์ž
class Cat {
  private name: string;
  private age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age  = age;
  },
  getName(): string {
    return this.name;
  }
}
  • Generics
    Generic ์„ ์–ธ์œผ๋กœ ๋ฏธ๋ฆฌ ๋ฐ›์„ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
// ๋ฏธ๋ฆฌ ๋ฐ›์„ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” generic
var list:Array<number> = [1, 2, 3];

function identity<T>(arg: T): T {
    return arg;
}
  • Enums
    ์—ด๊ฑฐ ์ž๋ฃŒํ˜•(enumerated type)์€ ๊ณ ์ • ๊ฐœ์ˆ˜์˜ ์ƒ์ˆ˜๋“ค๋กœ ๊ฐ’์ด ๊ตฌ์„ฑ๋˜๋Š” ์ž๋ฃŒํ˜•์„ ์ง€์›ํ•œ๋‹ค.
const enum Directions {
    Up,
    Down,
    Left,
    Right
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
  • Declration File
    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ช…์„ธ์„œ ํŒŒ์ผ์ด๋ฉฐ, ํ™•์žฅ์ž๋Š” .d.ts๋กœ ๋˜์–ด ์žˆ๋‹ค. tsconfig.json์— ๊ธฐ์ˆ ํ•˜๊ฑฐ๋‚˜, reference๋กœ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๋ฏธ๋ฆฌ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, Declartion File์„ ์ฐธ์กฐํ•˜๊ฒŒ ํ•ด์ฃผ์–ด์•ผ์ง€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.
    typings : https://github.com/typings/typings
    definity : http://definitelytyped.org/
// jquey datepicker ์‚ฌ์šฉ ์˜ˆ์‹œ.
interface JQueryStatic {
  datepicker: () => any;
}

// declare๋กœ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉ. ์„ ์–ธํ•˜์ง€ ์•Š์œผ๋ฉด $ is not undefined ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;

Javascript vs TypeScript ๊ฐ€๋…์„ฑ

Javascript๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ

jQuery.ajax(url, settings);

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด url๊ณผ settings๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.
url์ธ ๋ณ€์ˆ˜๋Š” ์•„๋งˆ string์œผ๋กœ ์ถ”๋ก ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, setting ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒด๋ผ๊ณ  ์ถ”๋ก ์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ‹€๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. Javascript์—์„œ ์ œ๊ณต๋˜๋Š” code๋งŒ์œผ๋กœ๋Š” ํ˜•์‹์ด๋‚˜, return์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์˜ˆ์ธกํ•˜๊ฑฐ๋‚˜ ์•Œ์ˆ˜๊ฐ€ ์—†๋‹ค. ์ฆ‰, ์•Œ๋ ค์ง„ ์ •๋ณด๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค. ๋‹จ์ง€ ์ถ”๋ก ์ผ ๋ฟ์ด๋‹ค. ajax function์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฌธ์„œ ๋˜๋Š” ์ œ๊ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ด์•ผํ•˜๋ฉฐ, ์ด ๋ฌธ์„œ๊ฐ€ ์˜ˆ์ „ ๋ฒ„์ „์˜ ๋ฌธ์„œ์ผ ์ˆ˜ ๋„ ์žˆ๋‹ค.

Typescript๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ

ajax(url: string, settings?: JQueryAjaxSettings): JQueryXHR;

interface JQueryAjaxSettings {
  async?: boolean;
  cache?: boolean;
  contentType?: any;
  headers?: { [key: string]: any; };
  //...
}

interface JQueryXHR {
  responseJSON?: any; //...
}

ํ•จ์ˆ˜ ์ž์ฒด๋งŒ ๋ณด๋”๋ผ๋„ url์€ string type์ด๋ฉฐ, setting๋Š” optionalํ•œ JQueryAjaxSettings type์œผ๋กœ ๋˜์–ด ์žˆ๋‹ค.
๋˜ํ•œ, ์ด ํ•จ์ˆ˜๋Š” JQueryXHR์„ returnํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.
Javascript๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์— ๋น„ํ•ด ๊ตฌํ˜„ ์ฝ”๋“œ๊ฐ€ ๋” ๊ธธ์–ด์กŒ์ง€๋งŒ, ์ด์ „ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋ฌธ์„œ๋‚˜ ์‹ค์ œ ๊ตฌํ˜„ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š๊ณ ๋„, ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ดํ•ด๋„์™€ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ฃผ๋Š” ์ž‘์šฉ์„ ํ•˜๊ณ  ์žˆ๋‹ค.

---- Next Step ----

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์„ค์น˜

  1. npm์ด ๊ธฐ๋ณธ์œผ๋กœ ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  2. npm install -g typescript

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ ์˜ˆ์ œ

ํŒŒ์ผ์€ .ts ํ™•์žฅ์ž๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, tsc ์ปค๋งจ๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋ฉด .js ํŒŒ์ผ๋กœ ๋นŒ๋“œ(์ƒ์„ฑ)๋œ๋‹ค.

TSD

TypeScrpt Definition Manager์˜ ์•ฝ์ž๋กœ, Declaration File ๊ด€๋ฆฌ๋ฅผ ์ง€์›ํ•œ๋‹ค.

npm install -g tsd
tsd install jquery
โš ๏ธ **GitHub.com Fallback** โš ๏ธ