1. 타입 스크립트가 등장하게 된 계기
자바스크립트는 본래 간단한 프로그래밍을 위해 만들어졌기 때문에 웹 브라우저에서만 작동하고, 유연하게 설계되었다는 장점이 있었다. 하지만 자바스크립트의 인기가 더욱 커지고 Node.js가 등장하게 되면서 웹 브라우저 외의 환경에서도 사용이 가능해졌고 활용도가 높아지면서 더 복잡한 프로그래밍에도 널리 사용이 가능해졌다.
이렇게 되면서 자바스크립트의 장점인 '유연함'과 자유로움은 곧 버그 발생 가능성이 높다는 문제점을 야기하게 되었고 더욱 안정적인 프로그래밍을 위해서 타입 스크립트가 등장하게 되었다. 이로써 타입 스크립트는 자바스크립트의 문법은 유지한 채, 타입과 같은 안정적인 문법이 추가된 자바스크립트의 확장된 언어라고 할 수 있다.
2. 자바스크립트의 한계점
1) 자바스크립트는 동적 타입 시스템이다. 곧 정적 타입 시스템(자바, c언어)과 달리 변수의 타입들을 런타임 중에 결정한다.(정적 타입 시스템처럼 우리가 직접 타입을 정의하지 않는다. ex.파이썬, 자바스크립트)
2) 변수의 타입이 고정적이지 않고 런타임 도중에 변경된다(유연함).
3) 타입으로 인한 오류 발생 시, 정적 타입 시스템같은 경우 실행 전에 이미 검사하여 즉시 실행이 안되지만 동적 타입 시스템인 자바스크립트는 즉시 실행이 멈추지 않고 나중에 갑자기 에러가 나는 등의 문제가 발생한다. 즉 개발자에 의한 타입 실수를 잡아주지 못하여 나중에 더 큰 문제를 발생시킨다.
4) 하지만 정적 타입 시스템은 실행 전에 타입 검사를 하여 안정적이라는 장점과 동시에 모든 변수에 타입을 명시해야 하기때문에 타이핑 양이 엄청나다는 단점이 있다.
타입 스크립트는 독특한 타입 시스템(점진적 타입 시스템)을 가지고 있다 -> 정적 + 동적 타입 시스템의 장점을 모두 가지고 있어 안정적이면서도 유연하다. 정적 타입 시스템처럼 타입 오류가 나면 알려주기 때문에 안전하면서, 일일히 모든 변수에 타입을 지정하지 않아도 타입이 명시되어 있지 않은 변수는 '점진적 타입 추론'을 통해 타입을 자동으로 인지한다.
3. 타입스크립트는 어떻게 동작할까?
1) 대다수의 프로그래밍 언어는 고급언어에 가깝다. 따라서 사람이 이해하기 쉬운 프로그래밍 언어를 기계어로 변환하는 '컴파일(Compile)을 통해 컴퓨터가 이해할 수 있는 언어로 변환하는 작업을 거쳐야 한다. 컴파일된 언어 = 바이트 코드
컴파일 과정은 프로그래밍 언어를 -> AST(추상 문법 트리)구조로 만들고 쪼개어 -> 바이트 코드로 변환한다.
2) 하지만 타입 스크립트의 경우 AST로 변환하고, AST를 보고 타입 검사를 먼저 실행 하여 문제 발생시 컴파일을 중단하고, 타입 검사 성공 시에는 바이트 코드가 아닌, 자바스크립트 코드로 변환한다. 그리고 컴파일이 종료된다.
이렇게 실행 전 타입 검사를 거쳐 컴파일된 자바스크립트 코드는 타입 검사를 통과한 비교적 안전한 자바스크립트 코드인 것이다. (타입 관련 코드들은 컴파일 시 모두 사라진다)
이렇게 컴파일된 자바스크립트 코드를 웹 브라우저나 Node.js환경에서 실행하면, 다시 한번 컴파일 과정을 거쳐 바이트 코드로 변환된다.
+ 컴파일과 인터프리터
브라우저에서 실행되던 자바스크립트는 전통적으로 컴파일이 필요없는 대표적인 인터프리터(interpreter) 언어였는데요. 브라우저나 Node.js는 우리가 작성한 자바스크립트 코드를 있는 그대로 이해하고 바로 실행할 수 있기 때문입니다.
컴파일(compile)은 소스 코드를 특정 플렛폼에서 실행 가능한 형태로 변환하는 과정을 의미하는데요. 기존에는 C++나 Java와 같이 자체 타입 시스템을 가진 프로그래밍 언어에서 주로 다뤄지던 개념이었으나, 타입스크립트의 등장 이후로는 자바스크립트에서도 컴파일이라는 용어를 심심치 않게 들을 수 있게 되었습니다.
자바스크립트 대신에 타입스크립트로 코드를 작성하는 것이 보편화됨에 따라 이제 많은 자바스크립트 프로젝트에서 컴파일 과정이 필요하게 되었습니다. 브라우저는 적어도 아직까지는 타입스크립트 코드를 있는 처리할 수가 없기 때문인데요. 따라서 개발 단계에서는 타입스크립트로 코드를 작성하지만, 배포할 때는 반드시 코드를 자바스크립트로 변환해줘야 하죠.
3. Node.js환경에서 typescript 실행 해보기
1. npm init 하여 패키지 환경 셋팅
node에서 사용하는 문법의 타입들을 설치
typescript 컴파일러 전역으로 설치
npm init
npm i @types/node
npm install typescript -g
4. 설치가 잘 됐는지 tsc(타입컴파일러) 버전 확인
$ tsc -v
5. index.ts 작성 후 tsc로 컴파일 해보기
//index.ts파일 작성
console.log("hello typescript");
const a: number = 1;
// 컴파일 하기 -> 컴파일된 자바스크립트 파일 생성됨
tsc src/index.ts
6. 컴파일된 자바스크립트 파일 생성됨 확인, index.js에서는 타입이 모두 사라짐 확인
- node에서 컴파일된 자바스크립트 코드 정상 실행됨 확인
node src/index.js
하지만 일일히 개발중에 tsc로 매번 컴파일, node로 확인할 수 없으니 ts-node 설치(ts를 즉시 실행까지 한번에 가능한 패키지다)
npm install ts-node -g
ts-node src/index.ts //실행 했더니 에러 발생
❗ts-node실행 시 에러 발생 : Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
ES모듈을 사용하려면 package.json에 "type": "module"을 추가 했더니 .ts 파일을 실행 못한다는 또 다른 에러 발생.. 다시 제거하였다.
현재 자바스크립트 생태계에서는 여러 종류의 모듈 시스템이 공존하고 있다. Node.js와 ts-node에서는 CommonJS모듈을 사용하는 것과 같이 컴파일 시 module 종류를 지정하여 맞춰주어야 하는 문제 같다.
-> 결론 : Node.js가 CommonJS을 지원하기 때문에 ts-node를 사용할 때에 tsconfig.json 파일에 컴파일러옵션에 "module": "CommonJS"를 사용해야 한다. tsconfig.json 파일 생성 후, 컴파일러 옵션에서 "module" : "CommonJS" 를 설정해주니 정상 작동
// tsconfig.json 파일 생성
{
"compilerOptions": {
"preserveValueImports": false,
"module": "CommonJS"
}
}
❗ 하지만 컴파일된 코드를 Node.js의 구식 버전과 같이 CommonJS를 모듈 시스템으로 사용하는 실행 환경에서 돌릴 게 아니라면, 표준으로 자라잡고 있는 ES 모듈의 문법을 사용해서 컴파일해야 할 것이다. 이럴 경우 "module" 옵션을 "es6"으로 지정해주면 된다.
{
"compilerOptions": {
"preserveValueImports": false,
"module": "es6"
}
}
ts-node 정상 작동 확인!
하지만 이렇게 잘 되다가도 또 .ts에러가 나는 경우가 발생했다.... ts-node는 Node 20 버전 이상에서는 더 이상 동작하지 않는다고 한다. 따라서 ts-node 대신 tsx를 사용을 권장한다. tsx는 단 한번의 명령어로 타입스크립트 코드를 실행시켜주는 도구다.
npm i -g tsx
tsx src/index.ts
-> 사실 tsc로 컴파일을 실행할 때 아래와 같이 module 옵션을 지정해 줄 수 있는데, 매번 일일히 tsc로 모듈 지정하여 실행할 수는 없고 옵션들이 많아질 수록 작성이 길어지게 되니 tsconfig 파일에서 여러가지 옵션들을 설정해 놓면 편리하다.
$ npx tsc --module es6 index.ts
다음 글에서는 tsconfig.json 옵션에 대해 간단히 알아보도록 하자.
<참고>
위 내용은 인프런 이정환 '한입 크기로 잘라먹는 타입스크립트' 강의를 공부하며 작성하였습니다.
'JavaScript > TypeScript' 카테고리의 다른 글
Typescript 앱 생성하기(초기 셋팅 방법) (0) | 2024.11.28 |
---|---|
[TypeScript] tsconfig.json 설정 옵션 알아보기 (0) | 2024.10.22 |
[TypeScript] 타입스크립트란 무엇인가? 타입스크립트 동작 원리에 대하여 (0) | 2024.03.08 |
[TypeScript] props으로 받은 함수의 타입 지정하기 (0) | 2022.12.01 |
[TypeScript] React.KeyboardEventHandler<HTMLInputElement> 에서 event.target.value 에러 (0) | 2022.12.01 |