TIL_171106 TypeScript

자바스크립트는 왜?
자바스크립트는 변수타입이 없는데도 값의 타입은 있다.
-> 메모리를 할당할 때에, 어느정도의 메모리를 할당할지(크기) 정해야하기 때문에

자바스크립트는 변수타입이 없기 때문에, 런타입에러에 대비해야함 (항상 형체크)
-> 타입스크립트를 쓰면서 문제 해결

TypeScript

  • AltJS(JavaScript의 대체언어)의 하나로써 JavaScript(ES5)의 Superset(상위확장)
  • 기존의 JavaScript(ES5) 문법을 그대로 사용가능
  • ES6의 새로운 기능들을 사용하기 위해 Babel과 같은 별도 Transpiler를 사용 불필요
  • ECMAScript의 업그레이드에 따른 새로운 기능이 지속적으로 포함
  • js로 기본 트랜스파일링은 ES3를 기준으로 함
  • 선언문과 할당문을 한번에 줄 경우 자동으로 타입 선언
  • 할당해주던지, 선언해주던지를 하지 않으면 any 타입으로 설정되어 타입스크립트의 의미를 상실
  • 정적 타이핑 지원 (변수의 타입을 선언할 수 있어, 잘못된 타입이 할당되면 컴파일러는 에러 발생)

enum

  • 상수들의 집합. 변하지 않을 값들의 모임
  • 열거형은 숫자값 집합에 이름을 지정한 것
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    enum Color1 {Red, Green, Blue};
    let c1: Color1 = Color1.Green;
    console.log(c1); // 1
    enum Color2 {Red = 1, Green, Blue};
    let c2: Color2 = Color2.Green;
    console.log(c2); // 2
    enum Color3 {Red = 1, Green = 2, Blue = 4};
    let c3: Color3 = Color3.Blue;
    console.log(c3); // 4

TypeScript Class

  • Typescript 클래스는 클래스 바디에 멤버 변수를 사전 정의 해야함. (기본은 public)
  • ES6는 바디에 메소드만 선언할수 있었다. (멤버변수 선언 안됨)

접근 제한자 (Access modifier)

  • Typescript는 public, private, protected 접근 제한자를 지원
  • 접근제한자가 사용된 생성자의 파라미터는 암묵적으로 멤버 변수로 정의
  • -> 생성자 내부에서 별도의 초기화없이도 암묵적으로 초기화가 수행
접근가능성 public protected private
클래스 내부
자식 클래스
클래스 인스턴스

추상 클래스

  • 추상클래스는 추상 메소드와 일반 메소드를 가질 수 있음
    • 추상 메소드 : 선언만 있음
    • 일반 메소드 : 함수바디가 있음
  • 직접 인스턴스를 생성할 수 없음(함수바디 없음) only 상속만을 위해 사용
  • 추상 클래스를 상속받는 클래스는 추상 클래스의 추상 메소드를 반드시 구현하여야 함
  • 상속받는 클래스마다 실제 구현이 각각 다르다는 가정하에, 협업 시 규칙을 정해서 빠뜨리지 않도록할 때에 사용

TypeScript - interface

  • 협업 시, 타입 체크 및 의사소통을 위해 많이 사용
  • 관습적으로 이름앞에 ‘I’를 붙임
  • 클래스가 아니기때문에 상속 ‘extends’의 개념이 없고, 구현 ‘implements’의 개념이 있음
  • -> 즉, 인터페이스로 설정해놓은 것을 ‘준수해서 만들라’ 는 의미
  • -> 인터페이스의 프로퍼티 부분은 인스턴스 생성시 선언해 주고, 메소드 부분은 함수바디를 작성해야 함
1
2
3
4
5
6
7
8
9
10
11
12
13
//요소의 타입을 규칙으로 정해놓음
interface Todo {
id: number;
content: string;
completed: boolean;
}
function addTodo(todo: Todo) {
console.log(todo.content);
}
const newTodo: Todo = { id: 1, content: 'typescript', completed: false };
addTodo(newTodo);

duck typing

  • 해당 인터페이스에서 정의한 값(멤버변수나 메소드)을 가지고 있다면 -> 해당 인터페이스를 구현한 것으로 인정
  • 덕 타이핑(duck typing) 또는 구조적 타이핑(structural typing)이라 칭함
  • 인터페이스를 일반 변수에 사용할 경우에도 덕 타이핑은 적용됨
  • 주안점: 인터페이스의 프로퍼티가 있는지 (이것 외에 없어야한다는 것은 아님)

Optional property

  • 인터페이스의 프로퍼티는 반드시 구현되어야 하지만 인터페이스의 프로퍼티가 선택적으로 필요한 경우에 사용
  • 프로퍼티명 뒤에 ?를 붙임
  • 생략하여도 에러가 발생하지 X

TypeScript - Generic

  • 타입별로 클래스를 추가해야하는 문제를 해결하기 위한 방안
  • 인스턴스 생성 시에, 타입을 넘겨서 생성함 <T>(함수에 인자를 넘기듯)
  • 함수에도 제네릭 사용 가능 -> 다양한 타입의 매개변수와 리턴 사용 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//T라는 별칭 (개발자가 정의)
class Queue<T> {
protected data = [];
push(item: T) {
this.data.push(item);
}
pop(): T {
return this.data.shift();
}
}
// number 전용 Queue
const numberQueue = new Queue<number>();
numberQueue.push(0);
// numberQueue.push('1'); // 의도하지 않은 실수를 사전 검출 가능
numberQueue.push(+'1'); // 실수를 사전 인지하고 수정할 수 있다
console.log(numberQueue.pop().toFixed()); // 0
console.log(numberQueue.pop().toFixed()); // 1
//인스턴스 생성시 String전용 Queue생성도 가능함
1
2
3
4
5
6
7
8
9
10
11
12
13
function reverse<T>(items: T[]): T[] {
return items.reverse();
}
const arg = [{name: 'Lee'}, {name: 'Kim'}, {name: 'Park'}];
// 인수에 의해 타입매개변수가 결정된다
const reversed = reverse(arg);
// reversed: {name: string}[] 을 타입으로 갖는다!!
console.log(reversed);
reversed.push({name: 100}); // Error
console.log(reversed);