Skip to content

01.Typescript

jungyoungtai edited this page Nov 30, 2016 · 16 revisions

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

Clone this wiki locally