📍 Typescript 란 ?

기존의 자바스크립트에 타입 개념을 추가한 언어.
컴파일의 결과물로 JavaScript 코드를 출력하고, 최종적으로 런타임에서는 이렇게 출력된 JavaScript 코드를 구동시키게 돼요.


🔎 Typescript를 사용하게 된 이유

동작 원리를 살펴보기 이전에, Javascript 에서 그치지 않고 Typescript가 등장하게 된 배경과 Javascript가 갖는 한계점이 무엇이었는지 살펴보아요!


Javascript의 한계점

Javascript는 동적 타입 언어이기 때문에 런타임에 변수의 타입이 정해지게 됩니다.

이로 인해 타입 관련 오류를 코드 실행 전에는 알기 어렵고, 잘못된 타입의 값이 전달되더라도 실행 시점까지 에러가 발생하지 않는 경우가 많게 되었죠.. 또한, 객체의 구조나 함수의 인수 형태에 대한 명확한 약속이 없어 개발자가 협업 시 코드의 의도를 파악하기 어렵다는 문제점도 있었습니다.

장점으로 느껴졌던 Javascript의 유연함은 프로젝트의 규모가 커질수록 유지보수성과 안정성을 크게 저하시켜 빌드하기 전까지 예측하기가 점점 힘들어졌어요.


Typescript의 장점

이러한 JavaScript의 한계를 보완하기 위해 등장한 언어가 JavaScript에 정적 타입 시스템을 추가한 Typescript 입니다.

JavaScript가 가진 문법과 동작 방식을 그대로 유지하면서도 타입 설정을 통해 코드의 안정성을 확보할 수 있게 되었어요.

이를 통해 타입 관련한 런타임 에러를 줄이고, 코드를 실행하기 전인 컴파일 시점에 타입 관련 에러들을 발견할 수 있게 되었습니다.


🧐 Typescript 는 정적 타입 언어이다 ?

Typescript가 정적 타입 시스템을 채택하고 있긴 하지만, 면밀히 따지자면 답은 NO 입니다.

그 이유는 무엇일까요 ?

1
2
let num: number = 1;
num = 'String'; // TypeError !

정적 타입 언어처럼 number 타입을 설정한 후, string 타입의 값을 할당하게 되면 코드 스페이스에 에러가 보여집니다.


하지만 만약 Javascript 처럼 num 변수에 아무런 타입을 설정하지 않는다면 어떻게 될까요?

1
2
let num = 1;
num = 'String'; // TypeError !

타입을 설정하지 않아도 설정했을 때와 같이 TypeError 를 반환합니다.


이것은 Typescript 가 변수에 담기는 초기값을 기준으로 타입을 추론하기 때문이죠.

이처럼 Typescript는 타입 설정을 기반으로 하지만, 직접 설정하지 않은 타입에 대해서는 자동적으로 추론해내는 점진적 타입 시스템 을 가지고 있습니다.

다음으로는 이러한 Typescript의 타입 시스템이 어느 시점에 이루어지는지 살펴보면 좋을 것 같네요 !


프로그래밍 언어의 동작 원리

        1. 코드를 AST 추상구문트리로 변환해요.
        2. AST 추상구문트리를 바이트 코드로 변환해요.
        3. 변환된 바이트 코드를 최종적으로 실행합니다.

프로그래밍 언어는 기계어를 사람이 제어할 수 있도록 고안된 언어이기 때문에, 컴퓨터에서 실행되기 이전에 기계어로 변환되는 과정이 필요합니다.

이 과정을 우리는 컴파일 한다고 말하고, 이 과정을 수행하는 것을 컴파일러라고 부릅니다.

컴파일 과정에서 기계어로 변환하기 이전에 한단계를 더 거쳐야하는데요. 바로 AST 추상구문트리입니다.


📍AST 추상구문트리

공백이나 주석과 같은 불필요한 세부 요소를 생략하고, 중요한 문법 구조만을 표현한 트리.


코드에서 불필요한 요소를 제거한 추상 구문 트리 형태로 변환한 이후 기계어로 변환하게 되는데, 이 기계어를 바이트 코드라고 말합니다. AST 에서 변환된 바이트 코드를 최종적으로 컴퓨터가 실행하게 되는거죠.


Typescript 의 동작 원리

typescript동작원리

간단하게 말하면, 위의 과정이 이루어지기 이전에 Typescript를 Javascript로 변환하는 과정이 추가됩니다.

먼저 AST 추상구문트리 형태로 변환해요. 그리고 AST 추상구문트리 형태에서 타입 검사를 실시하게 됩니다 !

만약 타입 검사를 실패하게 되면, 그대로 컴파일이 종료되고 TypeError를 반환하게 됩니다. 그렇지 않다면 타입 검사가 완료된 상태로 자바스크립트로 변환되고, 앞서 말했던 컴파일 과정을 다시 거쳐 프로그램에서 실행되는 거죠!

이렇게 Typescript는 타입이 검증된 Javascript를 실행하게 되기 때문에 동적 타입 언어인 Javascript에 비해 런타임 시 발생하는 에러가 줄어들게 되는 겁니다.


타입 검사

        📍 정적 검사 : 소프트웨어를 실행하지 않고 테스팅하는 기법.
        📍 동적 검사 : 실제 구현된 시스템을 실행하여 테스팅하는 기법.

Typescript가 수행하는 타입 검사는 정적 검사에 해당합니다. 코드를 실행하지 않고, 작성된 코드 내에서 타입이 잘못 사용된 곳이 없는지 검사하기 때문이죠 !

타입 검사의 방식을 간단히 말하자면, 다음과 같습니다.

함수의 인자를 최소 단위로 분리한 뒤, 최소 단위부터 결과값까지 거슬러 올라오면서 타입 검사를 실시합니다.
최소 단위부터 결과값까지 올라오던 도중 직접 설정되었거나 초기에 추론되었던 타입과 불일치하는 값이 있을 경우, TypeError를 반환하게 됩니다.

이 과정을 이해하는 데에 올리브영 테크 블로그 - 타입과 타입 시스템 글이 큰 도움이 되어서 참고해서 살펴보시면 많은 도움이 될 것 같아요 :D


참조

한입크기로 잘라먹는 타입스크립트

올리브영 테크 블로그 - 타입과 타입 시스템

캡틴판교 블로그 - 타입스크립트 핸드북