TypeScript 알아보기

갑작스런 면접 일정에 의해 빠르고 정확하게 짚으면서 알아가보자

타입스크립트의 특징

  • 컴파일 언어, 정적 타입 언어이다. JS는 인터프리터 언어지만, TypeScript는 컴파일 언어로 코드 수준에서 미리 타입을 체크하여 오류를 체크해낸다. 단 전통적인 컴파일 언어와는 다르게, 링킹 과정이 생략되어 있다.
  • 타입 기반 언어로써
    • 타입 스크립트 = 자바스크립트 + 타입
    • 컴파일 단계에서 타입 오류를 잡아낼 수 있고, 코드 어시스트 기능도 지원받을 수 있다.
    • 이것을 통해 암묵적 형변환, 호이스팅, 복잡성 문제를 해결할 수 있다.

컴파일러와 인터프리러의 차이점

## 컴파일러
- 컴파일러는 고급 언어로 작성된 프로그램 전체를 목적 프로그램으로 번역한 후, 링킹 작업을 통해 컴퓨터에서 실행 가능한 프로그램을 생성한다.
- 번역과 실행 과정을 거쳐야하기 때문에 번역 과정이 번거롭고 번역 시간이 오래 걸리지만, 한번 번역한 후에는 다시 번역하지 않으므로 실행 속도가 빠르다.
- 컴파일러를 사용하는 언어는 FORTRAN, COBOL, PASCAL, C, C++, PL/1등이 있다.
## 인터프리터
- 인터프리터는 고급 언어로 작성된 프로그램을 한줄 단위로 받아들여 번역하고, 번역과 동시에 프로그램을 한줄 단위로 즉시 실행시키는 프로그램이다.
- 프로그램이 직접 실행되므로 목적 프로그램이 생성되지 않는다.
- 줄 단위로 번역, 실행되기 때문에 시분할 시스템에 유용하며 원시 프로그램의 변화에 대한 반응이 빠르다.
- 번역 속도는 빠르지만 프로그램 실행 시마다 매번 번역해야 하므로 실행속도는 느리다.
- CPU 사용 시간의 낭비가 크다.
- 사용언어로는 BASIC, SNOBOL, LISP, APL 등이 있다.

컴파일러 인터프리터 공부를 하다보니 계속 지식에 대한 궁금증이 생긴다.

어셈블리어는 왜 있는 것일까? 기계어에서 바로 고급 언어로 진행하면 되는데 굳이 어셈블리어가 있는 이유는? 역사에 의해서 존해는 것 이전 저사양 시절에는 고급언어를 사용하는 것 보다 어셈블리어가 최적화가 잘 되어있었다.

좀 더 살펴보면 첫째 기계어에 대해 우리가 아는 것이 하나도 없다는 점이고, 기계어를 안다손 쳐도 소스코드를 하나하나 기계어로 번역하는 과정은 무지하게 헷갈린다는 점이다. 둘째는 C이외의 다른 언어에 대한 컴파일러 B를 새롭게 개발하는 상황이 왔을 때 이 과정에서 사용한 중간 단계 언어 번역기를 그대로 사용할 수 있다는 이점이 있기 때문이다. 셋째는 기계어는 기계마다 그 내용이 다르기 때문에 기계가 바뀔때마다 기계에 맞는 기계어로 번역해야 하는데, 중간 단계 언어 번역기가 도입되면 이 과정이 아주 단순해 지기 때문이다.

어셈블리어는 기계어와 1:1로 대응되는 기호로 이루어진 언어로, 니모닉 언어라고도 한다.

  • 하드웨어 제어에 주로 사용되며, 언어의 호환성이 없다.
  • 컴퓨터가 직접 이해할 수 없으므로 어셈블리어로 작성된 프로그램은 어셈블러를 사용하여 기계어로 번역해야 한다.

컴파일과 런타임의 동작 원리 및 과정

정적 타입 언어와 동적 타입 언어의 차이점

컴파일 타임과 런타임

예시로 오버라이드와 오버로드를 들고 있다.

오버로딩은 매개변수의 타입과 길이를 이용해서 같은 메소드의 리턴 값을 다르게 만들어주는 형식이고 오버라이딩은 부모의 메소드를 자식 클래스로 가져와서 자신만의 정의로 재 정의해서 사용하는 것을 말하는데

오버로딩은 컴파일 과정에서 결정이 되고 오버라이딩은 런타임시 결정이 된다. 고로 메소드가 내용이 다르다면 컴파일, 매개변수 유형이 다르다면 런타임시 결정이 된다.

오러로딩은 인자의 타입만으로 어떤 메소드를 호출할 지 결정한다.

  • 런타임 => 어떤 프로그램의 실행되는 동안의 Time
  • 컴파일 => 고급 언어를 기계어로 변경하는 과정

바이트 코드 언어

Java와 C#이 바이트 코드 계열 언어이다. 소스 코드를 컴파일 하는 것까지는 컴파일 언어와 같은데 이 결과물이 가상 머신용 어셈블리코드, 즉 바이트 코드 형태이며 이걸 가상 머신이 실제 기계어로 한줄한줄 번역하여 실행한다.

컴파일러 실행 단계

  1. 구문 분석: 소스코드 파일을 릭어 개별 문법요소 단위로 자른후, 이 문법 요소들을 해석하여 추상 구문 트리를 생성한다. 이 과정에서 문법에 맞지 않는 소스 코드는 사용자에게 알려준다.
  2. 최적화 : 추상 구문 트리를 분석하여 최적화를 수행한다. 도달할 수 없는 코드를 식별하거나, 상수 표현식을 미리 계산해 두거나, 루프 풀기 등의 대부분의 최적화가 이 단계에서 수행된다.
  3. 코드 생성: 최적화된 구문 트리로부터 목적 코드를 생성한다. 목표 언어가 기계어일 경우, 레지스터 활당, 연산 순서 바꾸기 등 하드웨어에 맞는 최적화가 이단계에서 수행된다. 대부분의 하드웨어 최적화 알고리즘은 NP복잡도를 갖지만, 휴리스틱을 통해 많은 최적화가 수행된다.
  4. 링킹 : 목적 코드가 기계어일 경우, 여러 라이브러리 목적 코드를 묶어 하나의 실행 파일을 생성하게 된다. 이 과정은 링커에 의해 수행되며, 어떤 사람들은 링커를 컴파일러의 이부로 간주하지 않기도 한다.

인터프리터 실행단계

  1. 소스코드
  2. 인터프리터
  3. 실행

다시 타입스크립트로 돌아와서..(타입스크립트를 이해하기 위해서는 컴파일과 인터프리터 동작 방식에 대해서 알아야 했기에 돌아왔다.)

type

TypeScript는 MS에 의해 개발 / 관리 되고 있는 오픈소스 프로그래밍 언어이다. 대규모 애플리케이션을 개발하는데 JS가 어렵고 불편하다는 불만에 대응하기 위해 개발되었다.

TS는 스크립트 언어의 표준인 ES의 표준을 따르기 때문에 JS영역을 침범하지 않고 ES를 지원한다.

TS의 특징

가장 큰 특징은 type을 지정하는 것이다.

TypeScript = JavaScript + type

JS의 var와 같은 자료형 대신, string, number 같은 자료형을 지정함으로써 안정성을 확보한다. TS를 설치할 때 같이 설치되는 tsc는 컴파일 과정에서 타입 검사를 통해 에러없이 안정성이 확보되면 타입을 제거하고 최종적으로 JS코드를 생성한다.

내 언어로 정리를 해보자면 JS는 동적타입언어이다. 그렇기에 컴파일시 타입을 설정해주지 않아도 작동이 되지만 TS를 통해 컴파일시 타입 검사를 실시해 안정성을 높여주는 역할을 한다.

type이 생김으로 인해 몇가지 장점 이 생기는데 우선 변수에 type이 추가되어 안정성이 확보된다.
두번째로 type에 대한 예외 처리를 하지 않아도 된다.(런타임시 예외처리 설정) 가령 JS에서는 사용자 입력 값에 대해 예외처리를 위해 아래와 같이 코드를 작성할 수 있다.

if(typeOf(변수) !== "String"){
  // 예외처리
}

위와 같은 예외처리가 빈번하게 발생할 수록 오버헤드가 생기지만, typescript로 타입이 지정 될 시 위와 같은 예외처리 코드를 사용할 필요가 없다.

마지막 장점은 JS엔진의 최적화를 돕는다. JS엔진은 hot function(자주 호출되는 함수)에 대해 최적화를 수행한다.

var add = (a,b) => a+b;
`

JS엔진은 위 함수가 자주 호출되며, 인자 a,b가 정수형으로 들어오는 것을 확인했다. 엔진은 '아! 앞으로도 a,b는 정수가 들어오는구나 라고 가정을 하고 최적화를 수행하는데 갑자기 string이 들어오면 최적화가 해체된다. 이런 최적화와 해체 작업이 반복되면 성능이 저하되므로 TS에서는 type을 지정하고 컴파일 과정에서 검사하기 때문에 최적화 해체가 발생할 상황이 적어진다.

  1. type이 추가되어 안정성 확보
  2. type에 대한 예외처리 설정 불필요
  3. JS엔진에 최적화 작업 성능 증가

출처

https://skout90.github.io/2017/08/12/Typescript/1. typescript란/

정보처리기사 필기시험 - 시나공

https://kwangyulseo.com/2016/10/16/컴파일-타임과-런타임/

https://medium.com/sjk5766/typescript-란-37b5b6a6f884