Typescript는 정말 type-safe할까

Devhslee·2023년 9월 16일
post-thumbnail

아무 생각 없이 하루를 잘 보내다가 갑자기 든 생각.

내가 지금 사용하고 있는 Typescript는 저엉말로 type-safe한 언어일까?
물론 vanilla javascript보다는 백배천배 낫다. 프론트엔드에서 급하게 페이지를 만들기 위해 javascript를 사용할 순 있어도 백엔드에서 그랬다간... ;;..

우선 타입 특성과 관련하여 언어를 구분하는 기준을 구글링해서 찾아봤다.

타입 체크 시점에 따라

1) type check를 runtime 또는 compile-time에 하는지에 따라
Statically-typed LanguageDynamically-typed Language로 나눌 수 있다.

타입 변환 허용 유무에 따라

2) implicit type conversion (=서로 다른 타입간의 변환) 을 허용하냐 유무에 따라
Strongly-typed LanguageWeakly-typed Language로 나눌 수 있다.

(↓language들을 한 데 모아 구별한 도표)

그렇다면 TypeScript는?

TypeScript는 위의 도표에서 어느 위치에 넣어볼 수 있을까?

우선 타입체크 시점을 생각해보자. TypeScript 코드를 실행할 때를 생각해보면 문제가 있을 시 컴파일 시 type error를 발생시킨다.

그렇다면 TypeScript를 Statically-typed Language라고 생각할 수 있을 것이다. 다만 절대적인 Static typing을 하는 것은 아니다. 이 글을 참고했다.

위 글에선 Optional Static Typing 이라는 개념이 등장한다.

TypeScript는 기본적으로 JavaScript를 기반으로 만들어졌기 때문에 Dynamic typing이 가능하다. 요컨대 vanilla javascript 처럼 type 명시 없이도 충분히 사용이 가능하다는 뜻이다.

function example1(a, b) {
	return a + b;
}

console.log(example1('hello', 4)); // 결과: hello4

이 경우 example()안에 인풋 파라미터로 문자열을 넣어도 compile-time에 에러를 발생시키진 않는다.

이제 저기서 type을 명시하게 되면 compile-time에서 example()의 파라미터 타입이 number인지 체크하게 될 것이다. 그렇게 되면 인풋 파라미터로 number 이외의 타입이 들어가면 컴파일 시에 에러를 마주하게 된다.

function example2(a: number, b:number): number {
	return a + b;
}

console.log(example2('hello', 4)); // error!

요컨대 type을 명시한 부분에 대해서는 static-typing이 적용될 것이고, 그렇지 않은 부분에 대해서는 dynamic-typing이 적용되는 것이다.

그럼 type conversion 여부에 대해서도 연관지어 생각해볼 수 있겠다.
위의 example1과 같이 구현한 함수에 대해서는 내부에서 type conversion이 일어날 수 있고, example2와 같이 구현한 함수에 대해서는 불가능할 것이다.


그래서 TypeScript는?

그래서 내가 내린 결론은,

TypeScript 자체는 type-safe한 코드를 작성할 수 있게끔 지원해주지만,
개발자가 어떻게 짜느냐에 따라 코드에 그렇지 않은 부분이 존재할 수 있다는 것이다.

당장 나의 경험만 생각해봐도, 메서드 파라미터로 들어오는 객체에 대해 클래스나 인터페이스를 정의해주기 귀찮아서 타입을 any(!)로 써둔 적이 없진 않았다.

하지만 디버깅과 유지보수를 위해 type을 빡세게 체크하는 건 권장되어야 하는 부분이고, TypeScript다운 코드를 짜기 위해 계속 고민해야 하는 것 같다.

그렇다면 Type-Safety를 보장하기 위한 방법이 있을까? 이에 관한 좋은 글을 발견해서 다음 포스트에 정리해 두었다.

profile
코딩-버그-좌절-해결-희열

0개의 댓글