Typescript (타입스크립트)
타입스크립트는 좀 특이한 언어이다. python이나 Ruby처럼 인터프리터(Interpreter) 언어도 아니고, 그렇다고 Java나 C처럼 Lower-level language도 아니다. 대신 더 높은 수준의 언어(High-level language)인 JavaScript 언어로 컴파일된다. 그래서 자바스크립트와 타입스크립트의 관계는 필연적일 수밖에 없으며, 타입스크립트를 좀 더 명확히 알기 위해서는 이 관계를 먼저 정확하게 알아야 한다.
Typescript와 Javascript 관계
타입스크립트를 한 번이라도 접해봤다면 제일 처음 듣는 개념은 이것일 것이다.
"Typescript is a superset of Javascript."
한글로는 "타입스크립트는 자바스크립트의 상위 집합이다"라는 말이다. 아주 멋진 말이며 저명한 사실이다. 그런데 이 말이 무슨 말인지 정확하게 알고 있는 사람은 많지 않다. 단순히 "자바스크립트의 기능보다 더 많은 기능을 제공해 주니깐 상위 집합이지."라고 생각하곤 한다. 물론 틀린 말은 아니지만, 이렇게 남에게 설명해 주려고 하니 제대로 모르는 사람이 된 기분이 든다. 좀 더 알아보자.
"자바스크립트 프로그램은 문법 오류가 없지 않은 한, 또한 타입스크립트 프로그램이다." 우리는 이 말을 이해해 볼 필요가 있다. 타입스크립트의 타입 검사기는 우리의 코드에 몇 가지 이슈를 표시해 줄 수는 있지만 이거는 별도의 독립적인 문제이다. 타입스크립트는 여기에 개의치 않고 우리의 코드를 파싱할 것이며, 자바스크립트 코드로 내보내 진다. 또한 타입스크립트 파일은 .ts, .tsx의 확장자를 갖고, 자바스크립트 파일은 .js, .jsx의 확장자를 갖는다고 절대 다른 언어가 아니다. 우리의 .js 파일 안에 있는 코드는 타입스크립트이다. index.js를 index.ts로 바꾼 것에 지나지 않는다. 이 모든 것이 Typescript는 Javascript의 상위 집합이기에 가능한 것이다. 이 말은 중요하기 때문에 몇 번 반복하겠다.
이것은 이미 존재하는 자바스크립트 코드 베이스(codebase)를 타입스크립트로 마이그레이션(migration)할 때 매우 유용하다. 왜냐하면 다른 언어가 아니기 때문이다(자바스크립트 코드 베이스의 언어를 Java로 바꾼다는 것과는 정반대의 말인 거다). 마이그레이션 하는 방법은 나중에 좀 더 자세히 다뤄 보겠다.
여기까지 읽었을 때, 자바스크립트와 타입스크립트가 같은 것이라는 느낌을 받았다면, 매우 만족한다. 그렇다면 한 가지 더 생각해 보자. 모든 자바스크립트 프로그램이 타입스크립트 프로그램이라고 할 수 있다면, 그 역도 성립할까? 정답은 아니다. 모든 타입스크립트 프로그램은 자바스크립트 프로그램이라고 할 수 없다. 이유는 타입스크립트는 현재 자바스크립트에서 지원하지 않는 문법들을 지원하고 있다. 예로 이 글을 쓸 기준으로 ES2019에서는 "optional chaining"이라는 문법이 지원되지 않지만 타입스크립트 3.7 버전 이상에서는 이 문법을 지원하고 있다. 그리고 이 부분은 수학 시간에 배운 집합의 개념을 가지고 옆 그림을 해석해 봐도 역이 성립할 수가 없는 것이다.
코드로 설명하자면 아래와 같다.
function hello(name: string) {
console.log(`Hello, ${name}!`);
}
위 코드는 타입스크립트에서 매우 잘 작동하는 코드지만, 자바스크립트를 사용하는 node나 크롬 개발자 콘솔 같은 프로그램에서는 에러가 발생할 것이다.
자바스크립트가 위 코드를 해석하지 못하는 이유는 : 가 타입스크립트의 특별한 기호이기 때문이다. 한 가지 예를 더 살펴보자.
타입스크립트 프로그램에서는 타입스크립트의 타입 검사기가 문제점을 미리 말해준다. 타입스크립에게 명시적인 타입을 전달해 주지 않으면, 위와 같이 타입스크립트의 타입 검사기는 타입이 없는 부분을 알려준다. 이와 같은 항상 "에러를 발생시키는 코드"가 아니더라도 미리 알려주는 것이다. 뿐만 아니라 타입을 전달해주지 않더라도 문제점를 미리 잡아낼 수 있다. 아래 예제를 보자.
자바스크립트 프로그램은 보다시피 어떠한 경고도 우리에게 하지 않는다. 여기서 타입스크립트의 목적을 알 수가 있다. 타입스크립트는 코드의 실행 없이 런타임에 예외를 발생시키는 코드를 미리 탐지하는 것이다. 자바스크립트 프로그램은 실행(run) 하지 않았다면 저 오류를 알지 못했을 것이다. 그리고 실행하고서야 비로소 알게 된다.
이처럼 타입스크립트는 타입을 적어주지 않아도 오류를 미리 잡을 수 있다. 하지만, 개발자가 타입을 명시적으로 전달해 준다면 훨씬 더 철저한 작업을 통해 타입 불일치로 인한 오류를 많이 줄일 수 있다.
// index.ts
let person = [{ name: 'jacob', ago: 22 },
{ name: 'jung', ago: 24 },];
console.log(person[0].age);
위 예제는 철자 오류로 실수를 했고, 콘솔에서는 올바르게 호출했지만, 타입스크립트에서는 아래와 같이 오류가 발생한다.
타입스크립트는 어떤 게 정확히 오류인지는 모르더라도 항상 짚어낸다. 그렇다고 오류의 위치가 정확한 건 아니다. 위에 코드에 타입을 전달하여 개선해보자.
개발자가 타입을 전달해준 덕분에 정확하게 오류의 위치를 짚어내 준다. 그리고 처음부터 타입을 넘겨줬다면 코드를 치고 있는 순간에 타입스크립트의 타입 검사기가 미리 빨간 줄로 잘못되었다고 알려준다, 놀랍지 않은가. 동적 언어인 자바스크립트를 정적 언어처럼 쓸 수 있게 해 주다니! 이거를 다시 벤 다이어그램(Venn diagram)으로 나타내 보자.
이제 위에서 말한 명제를 좀 더 말을 추가할 수 있는 그림이 되었다.
모든 자바스크립트 프로그램은 타입스크립트 프로그램이다. 하지만 일부 자바스크립트 및 타입스크립트 프로그램만 타입 검사를 통과한다.
그런데 여기서 또 다른 궁금증이 생긴다. 타입스크립트의 타입 검사만 통과하면 오류가 발생하지 않을까? 정답은 당연히 "아니요"다.
const person: string[] = ['jacob', 'jung'];
console.log(person[3].toLowerCase());
위 코드는 어떤 에러도 표시되지 않지만, 런타임(runtime)에 에러가 발생한다. 모든 예외를 막아주는 만능은 아니라는 말이다.(물론 위 경우는 막을 수 있는 방법이 있긴 하지만 나중에 다루겠다.)
타입스크립트에 대한 간단한 소개와 필요성을 언급해봤다. 자바스크립트만 사용한 개발자라면, 충분히 매력을 가지고 적용해 볼 수 있는 것 같다. 물론 스킬적이나 문법적인 거는 논지에서 벗어나기 때문에 최대한 제외했다.
이 글을 보고 Typescript에 대해 매력을 느꼈다면, 다음 글도 읽어보는 것을 추천한다.
'Typescript' 카테고리의 다른 글
더 나은 타입스크립트 작성하기 1 - Skills (0) | 2019.12.27 |
---|---|
[Typescript] 타입 시스템 (0) | 2019.12.21 |
[Typescript] Optional Chaining과 Nullish Coalescing (6) | 2019.12.17 |
[Typescript] 데코레이터(Decorator) (0) | 2019.12.09 |
[TypeScript] 타입스크립트 조건부 타입(Conditional Type) (0) | 2019.12.08 |