item 1. 타입스크립트와 자바스크립트의 관계 이해하기
•
타입스크립트는 자바스크립트와 밀접한 연관 관계이므로 서로 어떻게 연관되어있는지 제대로 이해하는 것이 중요하다.
◦
타입스크립트는 문법적으로 자바스크립트의 상위집합이다. 자바스크립트 프로그램에 문법 오류가 없다면 유효한 타입스크립트 프로그램이라고 할 수 있다.
◦
어떤 이슈가 존재한다면 문법 오류가 아니더라도 타입 체커한테 지적당할 가능성이 높다. 그러나 문법의 유효성과 런타임은 엄연히 다른 시점의 영역이다.
•
요약
◦
타입스크립트는 자바스크립트의 상위집합이다.
◦
모든 자바스크립트 프로그램은 타입스크립트 프로그램이다.
◦
타입스크립트는 별도의 문법을 가지고 있기 때문에 모든 타입스크립트 코드가 유효한 자바스크립트 코드는 아니다.
◦
타입스크립트는 자바스크립트 런타임 동작을 모델링하는 타입 시스템을 가지고 있기 때문에 런타임 시 발생할 가능성이 있는 오류를 찾아내고자 한다.
▪
그러나 모든 오류를 찾아내는 것을 기대해선 안 된다. 타입 체커를 통과하면서도 런타임 시 발생할 수 있는 오류들이 충분히 존재한다.
▪
당연히 자바스크립트에서는 허용되지만 타입스크립트에서는 오류가 발생하는 경우도 있다.
item 2. 타입스크립트 설정 이해하기
•
타입스크립트 컴파일러는 매우 많은 설정을 가지고 있으며 이런 설정들은 커맨드 라인에서 사용할 수 있다.
◦
tsc —noImplicitAny program.ts
•
설정 파일을 사용하면 타입스크립트를 어떻게 사용할지 명확해지므로 사용하는 것이 좋다.
◦
설정 파일은 tsc --init만 실행하면 간단하게 생성된다.
•
설정을 제대로 사용하려면 noImplicitAny와 strictNullChecks를 이해해야 한다.
◦
noImplicitAny는 변수들이 런타임 전에 미리 정의된 타입을 가져야 하는지 여부를 제어한다. 즉 암시적 any를 허용하지 않는다.
▪
다음은 noImplicitAny가 false일 때만 유효한 코드다.
function add(a, b) {
return a + b;
}
Java
복사
▪
타입을 정의하지 않으면 any로 간주되며 이를 암시적 any라고 부른다.
◦
strictNullChecks는 null과 undefined가 모든 타입에서 허용되는지 확인하는 설정이다.
▪
다음은 strictNullChecks가 false일 때 유효한 코드다.
const x: number = null;
TypeScript
복사
▪
strictNullChecks는 null과 undefined 관련 오류를 잡아내는 데 도움이 되지만 코드 작성을 복잡하게 만든다.
•
요약
◦
타입스크립트 컴파일러는 언어의 실행 구조에 영향을 미치는 몇 가지 설정을 tsconfig.json을 통해 관리한다.
◦
타입스크립트 설정은 tsconfig.json 파일을 통해 수정하자.
◦
자바스크립트 프로젝트를 타입스크립트로 마이그레이션하는 경우가 아니라면 noImplicitAny를 true로 해두는 것이 좋다.
◦
런타임 시, 객체가 초기화되지 않은 경우를 방지하기 위해 strictNullChecks를 설정하는 것이 좋다.
◦
타입스크립트가 엄격하게 체크하기를 바란다면 strict 설정을 고려해야 한다.
item 3. 컴파일과 타입이 관계 없음을 이해하기
•
타입스크립트 컴파일러는 크게 다음 두 가지 역할을 수행한다.
◦
최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랜스파일한다.
◦
코드의 타입 오류를 체크한다.
•
이 둘은 완벽히 독립적으로 동작한다.
◦
다시 말해서 타입스크립트가 자바스크립트로 변환될 때, 코드 내의 타입에는 영향을 주지 않는다.
◦
또한 자바스크립트의 실행 시점에도 타입은 영향을 받지 않는다.
•
이때문에 다음과 같은 일이 벌어진다.
◦
타입 오류가 있는 코드도 컴파일이 가능하다.
▪
컴파일은 타입 체크와 독립적으로 동작하기 때문에 타입 오류가 있는 코드도 컴파일이 가능하다.
▪
만약 오류가 있을 때 컴파일하지 않으려면 tsconfig.json에 noEmitOnError를 설정하거나 빌드 도구에 동일하게 적용하면 된다.
◦
런타임에는 타입 체크가 불가능하다.
▪
타입 체크는 런타임 시 발생하지 않는다.
▪
런타임 시 타입을 보장해주기 위한 다양한 기법들이 존재한다.
•
태그 기법
interface Square {};
interface Rectangle {};
type Shape = Square | Rectangle;
TypeScript
복사
•
타입과 값을 둘 다 사용하는 기법
class Square {};
class Rectangle extends Square {};
TypeScript
복사
◦
타입 연산은 런타임에 영향을 주지 않는다.
◦
런타임 타입은 선언된 타입과 다를 수 있다.
◦
타입스크립트 타입으로는 함수를 오버로드할 수 없으며 런타임 성능에 영향을 주지 않는다.
•
요약
◦
컴파일은 타입 시스템과 무관하다.
▪
타입스크립트 타입은 런타임 동작이나 성능에 영향을 끼치지 않는다.
▪
타입 오류가 존재하더라도 컴파일은 가능하다.
◦
타입스크립트 타입은 런타임에 활용되지 않는다. 런타임에 타입을 지정하려면 타입 정보 유지를 위한 별도의 방법이 필요하다.
◦
일반적으로는 태그된 유니온과 속성 체크 방법을 사용한다. 또는 클래스와 같이 타입스크립트 타입과 런타임 값 둘을 모두 제공하는 방법도 있다.
item 4. 구조적 타이핑에 익숙해지기
•
자바스크립트는 본질적으로 덕 타이핑 기반이다.
◦
어떠한 객체의 속성들이 특정 클래스의 속성을 모두 포함한다면 해당 클래스로서의 역할을 수행할 수 있다는 것이다.
•
타입스크립트는 이런 동작, 즉 매개변수 값이 요구사항을 만족한다면 타입이 무엇인지 신경쓰지 않는 동작을 그대로 모델링했다.
◦
따라서 타입스크립트는 구조적 타입 시스템을 사용한다.
•
요약
◦
자바스크립트가 덕 타이핑 기반이며 타입스크립트는 이를 모델링하기 위해 구조적 타이핑을 사용한다.
▪
어떤 인터페이스에 할당 가능한 값이라면 타입 선언에 명시적으로 나열된 속성을 가지고 있다.
◦
클래스 역시 구조적 타이핑 규칙을 다른다는 것을 명심해야 한다. 클래스의 인스턴스가 우리가 예상한 객체가 아닐 수 있다.
◦
구조적 타이핑을 사용하면 단위 테스트를 손쉽게 작성할 수 있다.
item 5. any 타입 지양하기
•
타입스크립트를 사용할 땐, any의 유혹에서 벗어나야 한다.
◦
any 타입에는 타입 안전성이 없다.
◦
any는 함수 시그니처를 무시해 버린다.
◦
any 타입은 코드 리팩토링 시 버그를 감춘다.
◦
any는 타입 설계를 감춰버린다.
◦
any는 타입 시스템의 신뢰도를 떨어뜨린다.
•
요약
◦
any 타입을 사용하면 타입 체커와 타입스크립트 언어 서비스를 무력화 시켜버린다.
◦
any 타입은 문제점을 감춰버리며 개발 경험을 불만족스럽게하고 타입 시스템의 신뢰도를 떨어뜨린다. 최대한 사용을 자제하라.