TypeScript 기초 : 타입의 정의와 의미
TypeScript는 JavaScript와 관계가 C와 C++의 관계와 비슷한다. 즉, TypeScript에서 JavaScript 문법을 사용한다고 해서 빌드가 안되는 것이 아니다. 오히려 TypeScript는 ECMAScript(ES)의 표준에 맞춰서 제작이 되고 있다.
타입정의 하는 방법
JS(JavaScript)에서 변수와 객체선언은 var를 사용해서 선언 혹은 정의를 할 수 있었다. 이 var는 기본적인으로는 5가지 타입(Primitive Data Type)을 갖고 있다(겉보기에는 타입이 없는 것 같지만, 내부적으로 타입을 갖고 있어야 한다. 이러한 타입은 사실 JS에서 자세히 다뤄야 한다).
1. Data Type (number, string, Object)
2. Dynamic type (undefined, number, string, Boolean, Array, Object)
3. Primitive Data (string, number, boolean, null, undefined)
4. Complex Data (function, Object)
이러한 내부적으로 갖고 있는 타입간 충돌이 일어날 경우 브라우저에서는 타입에러(Type Errer) 혹은 미정의에러(Undefined Error)메시지를 콘솔에서 확인할 수 있다.
간단한 예로 숫자가 들어 있는 변수에 특정 object의 키를 읽으려고 하는 경우에는 의도대로 동작이 안될 것이다.
TS(TypeScript)에서는 이러한 실수를 줄여주기 위해서 변수를 지정을 할때 타입을 명시(혹은 정의)할 수 있다. var로 변수 혹은 객체를 선언을 할때에는 뒤에 ":"를 두고 뒤에 타입이름을 명시하면 된다.
예시)
var foo : number;
foo = 2;
foo = "foo" // error
하지만, 위의 3번째 줄이 에러라고 해서 빌드한 결과가 에러는 아니다. 위의 세줄을 JS로 변환하면 다음과 같다.
예시)
var foo;
foo = 2;
foo = "foo";
JS에서는 엄밀하게는 "="의 역할이 참조를 의미하기 때문에 foo의 2가 "foo"라는 문자열(string)으로 참조가 바뀌게 된다. 이 경우가 간단한 예제에서는 문제가 없어 보인다. 하지만, 숫자(number)나 객체(object)를 인자로 받아서 계산을 하는 함수가 있다면, 원하는 결과와 다른 결과를 얻게 된다(그리고 그 결과 야근같은 추가 근무가 될 것이다).
때문에 TS에서 에러로 표시된 것은 가능하면 해결하는 습관을 갖는 것이 장기적으로 생각했을 때 큰 이득이 된다.
타입정의가 가능한 것들
타입정의가 가능한 것들은 JS에서 내부적으로 정의 된 타입보다 자세한 정의가 가능하다. 일단 앞서 언급했던 JS에서 갖는 5가지 타입이 정의 가능하며, TS 2.0 이후에는 null도 독립적인 타입처럼 정의하고 구분을 한다.
타입정의가 가능한 것들
1. JS에서 내부적으로 갖는 5가지 타입
2. TS에서 정의 되어 있는 class 이름
3. TS에서 정의 되어 있는 interface 이름
4. TS에서 정의 되어 있는 enum 이름
5. any 타입(JS의 기본 var 와 같이 모든 타입을 받음)
6. null 타입
7. 콜백함수(Function)와 화살표 함수
타입정의가 가능한 곳(위치)
변수 혹은 객체를 표기할 수 있는 곳은 거의 다 타입정의를 할 수 있다. 다만, 메서의 반환(리턴)값의 경우 메서드의 뒤에 표기를 한다. 이는 메서드의 첫줄로 타입을 확인할 수 있어 가독성의 이점을 준다. 단, 정의를 안한상태에서 리턴값이 있을 경우에는 에러가 아니다.
예시)
function func1(foo: number): number
{ return foo +1; }
function func2(foo: number) // no error
{ return foo +1; }
한 변수 혹은 객체에 여러 타입을 정의 하기
하나의 변수에 여러개의 타입을 정의한 것도 가능하다. 방법은 or연산과 같은 "|"을 통해서 정의가 가능하다. 메서드의 입력 인자에서 사용하는 경우 메서드 내부에서 타입을 구분해주는 코드가 있어야 에러 메시지가 뜨지 않는다.
예시)
function func1(foo: number | string)
{
if("string" === typeof(foo))
foo = Number(foo);
return foo + 1;
}
마찬가지로 반환(리턴)값의 타입을 정의 할때도 여러개의 타입을 정의 할 수 있다. 이 경우 여러개로 정의 된 타입중에 하나를 반환하면 된다.
예시)
function func2(foo: number): number | string
{
if(0 < foo){
return foo;
}else{
return "negative number";
}
}
타입 정의의 의미
정리하면서, 타입스크립트의 탄생배경은 대규모 프로젝트시에 어려움을 줄이기 위해 탄생된 만큼 소규모 웹 앱을 제작할때에는 오히려 타이핑을 더 해야 하는 등의 불편함을 초래 할 수 있지만, 반대로 규모가 커질 수록 개발자의 실수와 가독성을 높여주는 효과가 있다. 그중 핵심적인 기능이 타입정의라 할 수 있다. 타입정의가 되므로 IDE의 인텔리전트(코드 자동완성 및 추천기능) 기능을 이용도 쉬워지며, 능숙하지 못한 개발자의 실수를 줄여주는 효과가 있다. 사실 개발에서 시간을 많이 할애하는것은 타이핑보다는 디버그라는 점을 생각할때 큰 이점이라 할 수 있다.
참조
자바스크립트 타입에 대한 내용
w3schools.com