typeScript -1

이동근·2022년 9월 17일
0

타입스크립트

목록 보기
1/3

타입스크립트 알아보기

타입스크립트는 사용 방식 면에서 조금은 독특한 언어입니다. 인터프리터(파이썬, 루비)로 실행되는 것도 아니고, 저수준 언어(자바, C)되는 것도 아닙니다. 또 다른 고수준 언어인 자바스크립트로 컴파일 되며, 실행 역시 타입스크립트가 아닌 자바스크립트로 이루어집니다.

그래서 타입스크립트와 자바스크립트의 관계를 잘 이해한다면 타입스크립트 개발자로서 한 단계 성장 할 수 있습니다.


타입스크립트와 자바스크립트 사이의 관계

타입스크립트는 자바스트립트의 상위 집합이다. 또는 타입스크립트는 타입이 정의된 자바스크립트의 상위 집합이다.
자바스크립트 프로그램에 문법오류가 없다면, 유효한 타입스크립트 프로그래미라고 할 수 있습니다.

그런데 자바스크립트 프로그램에 어떤 이슈가 존재한다면 문법 오류가 아니더라도 타입체커에게 지적당할 가능성이 높습니다.
그러나 문법의 유요성과 동작의 이슈는 독립적인 문제입니다.

자바스크립트 파일이 .js(jsx) 확장자를 사용하는 반면, 타입스크립트 파일은 .ts(tsx)확장자를 사용합니다. 그렇다고 자바스크립트와 타입스크립트가 완전히 다른 언어라는 의미는 아닙니다. 타입스크립트는 자바스크립트의 상위집합이기 때문에 js파일에 있는 코드는 이미 타입스크립트라고 할 수 있습니다.

-> 이러한 특성은 기존에 존재하는 자바스크립트 코드를 타입스크립트로 마이그레이션하는데 엄청난 이점이 됩니다.

모든 자바스크립트 프로그램이 타입스크립트라는 명제는 참 이지만 그 반대는 성립하지 않습니다.

타입스크립트의 타입 시스템의 목표 중 하나는 런타임에 오류를 발생시킬 코드를 미리 찾아내는 것입니다.
타입스크립트는 타입 구문 없이도 오류를 잡을 수 있지만, 타입 구문을 추가한다면 훨씬 더 많은 오류를 찾아낼 수 있습니다.
(코드의 '의도'가 무엇인지 타입 구문을 통해 타입스크립트에게 알려줄 수 있기 때문에)

보면 state 객체가 잘못된건지, 함수가 잘못된 것인지 작성자의 의도를 파악할 수가 없다.

이런식으로 작성자의 코드가 어떤 의도인지 알려주게 되면 타입체커가 더 정확하게 오류를 잡아낼 수 있다.

타입스크립트 타입 시스템은 자바스크립트의 런타임 동작을 '모델링' 합니다.

다른언어 였다면 오류가 나겠지만, 타입스크립트 경우에는 두 줄 모두 문자열 '23'이 되는 자바스크립트 런타임 동작으로 모델링 됩니다.

타입스크립트의 도움을 받으면 오류가 적은 코드를 작성할 수 있습니다. 그러나 이상한 코드들처럼 null과 7을 더하거나, []과 12를 더하거나, 불필요한 매개변수를 추가해서 함수 호출하는 것을 당연하게 여긴다면 차라리 타입스크립트를 쓰지 않는 게 낫습니다.

오류들이 발생하는 근본 원인은 타입스크립트가 이해하는 값의 타입과 실제 값에 차이가 있기 때문입니다. 타입시스템이 정적타입의 정확성을 보장해 줄 것 같지만 그렇지 않습니다. 애초에 타잆시스템은 그런목적으로 만들어 지지 않았습니다.

타입스크립트 설정들

ts.config 파일에서도 설정 가능
ts.config 파일을 사용해야지 타입스크립트를 어떻게 사용할 께획인지 동료들이나 다른 도구들이 알 수 있습니다.
시스템과 관련된 설정도 할 수 있기 때문에 어떻게 설정하느냐에 따라 완전히 다른 언어로 느낄 수도 있다.

  • noImplicitAny: 변수들이 미리 정의된 타입을 가져야 하는지 여부를 제어합니다.
    (타입스크립트는 자팅ㅂ정보를 가질 때 가장 효과적이기 때문에, 되도록이면 noImplictiAny)를 설정해야 합니다.)
  • strictNullCheck : null과 undefined가 모든 타입에서 허용되는지 확인하는 설정

그 외에도 많은 설정들이 있기때문에 공식문서 찾아서 하면 된다.

3. 코드생성과 타입이 관계없음을 이해하기

큰 그림에서 보면 타입스크립트 컴파일러는 두 가지 역활을 수행한다.

  • 최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랩스파일 합니다.(transfile)
  • 코드의 타입오류를 체크 합니다.

타입스크립트가 자바스크립트로 변환될 때 코드 내의 타입에는 영향을 주지 않습니다.
타입스크립트 컴파일러가 수행하는 두 가지 역할을 되짚어 보면, 타입스크립트가 할 수 있는 일과 할 수없는 일을 짐작할 수 있습니다.

위의 두 역활을 각각 독립적인 역활을 하기 때문에

  • 타입 오류가 있는 코드도 컴파일이 가능합니다.

타입오류가 있는 데도 컴파일 된다는 사실때문에 타입스크립트가 엉성한 언어 처럼 보일수 있지만 코드에 오류가 있더라도 컴파일된 산출물이 나오는 것이 실제로 도움이 됩니다.
만약 오류가 있르때 컴파일 하지 않으려면
tsconfigdml noEmitOnError를 설정하거나 빌드 도구에 동일하게 적용하면 된다.

  • 런타임에는 타입체크가 불가능합니다.

타입스크립트의 타입은 제거가 가능합니다. 실제로 자바스크립트로 컴파일 되는 과정에서 모든 이터페이스, 타입, 타입구문은 그냥 제거되어 버립니다.

instanceof 는 런타임에 일어나지만, Rectangle은 타입이기 때문에 런타임 시점에 아무런 역할을 할 수 없습니다. 타입스크립트의 타입은 '제거가능' 합니다. 실제로 자바스크립트로 컴파일 되는 과정에서 모든 이터페이스, 타입, 타입 구문은 그냥 제거 되어 버립니다.

좀 더 명확하게 shape의 타입을 명시해 주려면, 런타임에 타입정보를 유지하는 방법이 필요합니다.
하나의 방법은 height의 속성이 존재하는지 확인해 보는것

다른방법으로
타입정보를 유지하는 방법으로 명시적으로 저장하는 '태그' 기법이 있습니다.

이 태그 기법은 Union 입니다. 이 기법은 런타임에 타입 정보를 손쉽게 유지할 수 있기 때문에, 타입스크립트에서 흔하게 볼 수 있습니다.

타입(런타임 접근 불가)과 값(런타임 접근 가능)을 둘 다 사용하는 기법도 있습니다. 두 개 다 클래스로 만들어서 사용하면 된다.

런타임: 프로그램이 실행이 되고 있는 동안의 동작

  • 타입연산은 런타임에 영향을 주지 않습니다.

string 또는 number 타입인 값을 항상 number로 정제하는 경우를 가정해 보겠습니다.

function asNumber(val: number | string): number {
  return val as number
}

변환된 js 코드를 보게 되면

function asNumber(val) {
  return val
}

이런식르로 타입을 강제해 주게 되어도 코드에는 아무런 정제 과정이 없습니다. asNumber는 타입 ㅕㄴ산이고 런타임 동작에는 아무런 연산을 미치지 않습니다.

  • 런타임 타입은 선언된 타입과 다를 수 있습니다.

boolean이 타입이기 때문에 boolean은 런타임에 제거됩니다.
그래서
타입스크립트에서는 런타임 타입과 선언된 타입이 맞지 않을 수 있습니다. 타입이 달라지는 혼란스러운 상황을 가능한 한 피해야 합니다. 선언된 타입이 언제든지 달라질 수 있다는 것을 명심해야 합니다.

  • 타입스크립트 타입으로는 함수를 오버로드 할 수 없습니다.

c++같은 언어는 동일한 이름에 매개변수만 다른 여러 버전의 함수를 허용합니다. 이를 오버로딩 이라고 합니다.
하지만 타입스크리브에서는 타입과 런타임의 동작이 무관하기 때문에, 함수 오버로딩은 불가능합니다.

하나의 함수에 여러 개의 선언문을 작성할 수 있지만, 구현체는 오직 하나뿐 입니다.

  • 타입스크립트 타입은 런타임 성능에 영향을 주지 않습니다.

타입과 타입 연산자는 자바스크립트 변환 시점에 제거 되기 때문에, 런타임의 성능에 아무런 영향을 주지 않습니다. 타입스크립트의 정적 타입은 실제로 비용이 전혀 들지 않습니다.

대신 타입스크립트에는 '빌드타임 오버헤드' 가 있습니다.

오버헤드: 어떤 처리를하기 위해 들어가는 메모리, 처리 시간 등을 의미한다.

오래된 런타임 환경을 지원하기 위해 호환성을 높이고 성능 오버헤드를 감안할지, 호환성을 포기하고 성능 중심의 네이티브 구현체를 선택할지의 문제에 맞닥뜨릴 수 있습니다.


출처: 이펙티브 타입스크립트, 저자 댄 배더캄

profile
하루하루 1cm 자라는 개발자

0개의 댓글