TypeScript의 주요 기능
Type Declaration
1 | let num: number; |
1 | function mult(x: number, y: number): number { |
Parameter의 type을 모두 명시해준 경우 Return type은 추론이 가능하므로 생략이 가능하다. Type은 any가 나오지 않게끔만 지정하면 된다.
void
: return을 하지 않는다. 사실은 undefined
가 return되지만 void
라고 한다.
Types of TypeScript
From JavaScript: boolean, null, undefined, number, string, symbol, object
Added in TypeScript: array, tuple, enum, any, void, never
void와 never 차이
never는 함수가 종료하지 않아 결코 return하지 않을 때 사용된다. 무한루프 혹은 Error 메시지를 throw할 때 return type이 never이다.
void는 return 값이 없을 뿐이지 함수는 종료한다.
array
1 | let list1: number[] = [1, 2, 3]; |
tuple
1 | let tuple: [string, number]; |
배열인데 고정된 element의 수만큼 type을 미리 선언한다.
enum
1 | enum Season {Spring, Summer, Fall, Winter}; |
Class
TypeScript가 지원하는 Class는 ES6의 Class와 유사하지만 몇 가지 고유한 확장 기능을 가진다.
1. Class Definition
ES6 Class와 다르게 constructor 외부, 즉 Class body에 Class field를 미리 선언해야 한다. 그렇지 않으면 Error가 발생한다.
1 | class Circle { |
constructor의 parameter에 Access Identifier를 사용하면 아래와 같이 선언할 수 있다.
1 | class Circle { |
2. Access Identifier
- public : Class 내부, Child Class 내부, Class Instance에서 접근 가능
- protected: Class 내부, Child Class 내부에서 접근 가능
- private: Class 내부에서만 접근 가능
Access identifier를 지정해주지 않으면 암묵적으로 public이 된다. 따라서 public으로 지정하고자 하는 Member variable과 method는 access identifier를 생략한다.
constructor parameter를 선언할 때 public를 붙이면 할당까지 이루어지고 Class 내부의 member variable이 된다. public을 쓰지 않으면 constructor 내부에서만 참조 가능한 지역 변수가 된다.
3. readonly Keyword
readonly
가 선언된 클래스 프로퍼티는 선언할 때 또는 생성자 내부에서만 값을 할당할 수 있다. 그 외의 경우에는 값을 할당할 수 없고 오직 읽기만 가능한 상태가 된다. 상수를 선언할 때 사용한다.
4. static Keyword
메소드 뿐만 아니라 프로퍼티도 static으로 지정할 수 있다.
5. Abstract Class
Abstract class는 하나 이상의 abstract method를 포함하며 일반 method도 가질 수 있다. Abstract method란 구현 없이 method 이름과 type만이 선언된 method를 말한다. 선언시 abstract
키워드를 사용한다.
Abstract class는 직접 instance를 생성할 수 없고 상속만을 위해 사용된다. Abstract class를 상속한 class는 반드시 abstract class의 abstract method를 구현해야 한다.
Interface는 모든 method가 abstract이다.
Interface
Interface는 일반적으로 type check를 위해서 사용된다. 변수, 함수, 클래스에 사용할 수 있다.
Interface는 여러가지 type을 갖는 property로 이루어진 새로운 type을 정의하는 것과 같다. Interface에 선언된 property와 method의 구현을 강제해서 일관성을 유지할 수 있게 한다.
1. Variable and Interface
1 | // Definition of interface |
필요에 따라서 새로운 타입을 생성하는 것과 같다. 함수의 parameter 선언시에도 interface를 사용하여 전달되는 argument의 type 형식을 제한할 수 있다.
2. Function and Interface
1 | // 함수 인터페이스의 정의 |
잘 안 씀
3. Class and Interface
1 | // 인터페이스의 정의 |
4. Duck Typing
Interface를 implements해서 구현하지 않아도, 해당 interface 내부의 property나 method를 모두 구현하면 type check에서 통과된다.
1 | interface IDuck { // 1 |
Interface IDuck을 명시적으로 implements하지 않은 RedheadDuck의 instance도 IDuck 내부를 완벽하게 구현했다면 type이 IDuck으로 인정된다.
즉, implements 여부가 아니라 interface 구현 여부가 check된다.
5. Optional Property in Interface
Interface 내부에서 ?
가 붙은 property는 구현을 생략해도 된다.
1 | interface StudentInfo { |
Generic
C나 C++ 등 정적 타입 언어에서는 함수 또는 클래스를 정의할 때 parameter나 return 값의 타입을 선언해야 한다. TypeScript도 정적 타입 언어이므로 정의 시점에 타입을 선언해야하는데, 함수 또는 클래스를 정의할 때 parameter나 return type을 선언하기 어려운 경우가 있다.
TypeScript는 선언시 타입을 지정하지 않으면 any타입이 되어 type check를 할 수 없게 된다. Stack이나 Queue를 구현하는 경우 배열에 어떤 type을 담을 것인지 정의할 때 확정짓기 어렵다. 이런 경우에 Generic을 사용한다.
1 | class Stack<T> { |
위의 class Stack을 정의할 때 타입을 따로 지정하지 않고 <T>
를 사용했다. <T>
는 Type Paremeter이며 Type의 약자이다. 어느 type이던 사용할 수 있음을 의미한다.
Generic은 선언 시점이 아니라 생성 시점에 타이블 명시해서 다양항 타입을 사용할 수 있도록 하는 기법이다.
1 | function sort<T>(items: T[]): T[] { |
위는 함수에서 Generic을 사용한 것이다. 어떤 type으로 이루어지는지는 모르지만 배열을 parameter로 받아서 sorting한 배열을 리턴한다.