FE/TypeScript

[TypeScript] 타입스크립트 너는 누구냣

mandelina 2022. 8. 22. 16:21

 타입스크립트는 프론트엔드 공부를 하며 자연스럽게 알게되었다.

실무에서 많이 사용되고 있고, 또 타입을 개발자가 지정해줄 수 있는 장점이 있어서 (물론 단점도 있긴 하겠지만) 코드가 개발자 의도에 맞게 돌아간다 정도만으로 알고 있었다. 지금까진 공식문서를 한바퀴 훑었고 , 이제는 본격적으로 공부하면서 중요한 부분들을 정리해보려 한다. 

 

 

 


 

1. 타입스크립트와 자바스크립트의 관계

 

타입스크립트는 자바스크립트의 superset이다.

 

superset 굉장히 오랜만에 들어보는 용어인데 ..^^

즉 해석하자면 타입스크립트가 자바스크립트의 상위집합이란 뜻이다. 

이 말은 .js 파일을 .ts로 바꾼다고 해도 달라지는 것은 없다라는 뜻이다.

따라서, 자바스크립트 코드를 타입스크립트로 마이그레이션 하는데에 큰 이점이 된다.

 

벤다이어그램으로 표현하자면 이런 상태이다.

 

 

 여기서 타입체커가 등장하게 되는데 타입스크립트 타입체커는 추가적인 타입 구문이 없어도 오류를 찾아낼 수도 있지만 , 타입 구문을 추가한다면 훨씬 더 많은 오류를 찾아낼 수 있다.

코드의 의도가 무엇인지 타입구문을 통해 타입스크립트에게 알려줄 수 있기 때문이다.

 

그럼 타입체커를 포함해서 그린 벤다이어그램은 다음과 같을 것이다.

 

타입스크립트와 자바스크립트의 관계
모든 자바스크립트는 타입스크립트이지만, 일부 자바스크립트(그리고 타입스크립트)만이 타입 체크를 통과한다.

 

 


 

 

2. 타입스크립트 설정

 

- 커맨드라인이나 tsconfig.json 설정 파일을 통해 사용할 수 있다. (되도록  tsconfig.json에서 하자)


여기서 우리가 이해해야할 설정 2가지

 

1. noImplicitAny : 변수들이 미리 정의된 타입을 가져야 하는지 여부 제어

 

2. strictNullChecks : null과 undefined가 모든 타입에서 허용되는지 확인하는 설정

 

  만약 null을 허용하고 싶다면 아래와 같이 명시적으로 드러내서 사용할 수 있다.

const x: number | null = null;

 

 

 


 

strictNullChecks는 타입스크립트가 처음이거나 마이그레이션중이라면 설정하지 않아도 괜찮다.

strictNullChecks를 설정하려면 noImplicitAny 를 먼저 설정하자.

 

추가적으로 이 모든 체크를 설정하고 싶다면 strict 설정을 하면 된다. (대부분 오류를 잡아낸다.)

 

 

 

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

 

타입스크립트 컴파일러의 역할 2가지

 

1. 최신 TS/JS를 브라우저에서 동작할 수 있도록 구버전의 JS로 transpile

2. 코드의 타입오류를 체크

 

여기서 중요한 점은 타입스크립트 컴파일러는 1번과 2번을 독립적으로 진행한다는 점이다.

이를 통해 타입스크립트가 할 수 있는일과 없는일을 짐작해볼 수 있다.

 

 

- 타입 오류가 있는 코드도 컴파일이 가능

( 컴파일은 타입체크와 독립적으로 동작하기 때문! )

 

- 런타임에는 타입체크 불가

( 이를 위해 런타임에 접근 가능한 타입 정보를 명시적으로 저장하는 tag기법을 사용하거나 class 같이 타입스크립트 타입과 런타임 값을 둘 다 제공 )

 

- 타입 연산은 런타임에 영향을 주지 않음

( 타입 단언문에 대해 배우면서 알아보기 )

 

- 런타임 타입은 선언된 타입과 다를수 있음

( 런타임에서는 타입체크가 불가능하기 때문 )

 

- 타입스크립트 타입으로 함수를 오버로드 불가능

( 오버로딩? 동일한 이름, 매개변수 타입만 다른 여러버전의 함수를 허용하는 것 )

 

- 타입스크립트 타입은 런타임 성능에 영향을 주지 않음

( 마찬가지로 타입과 타입 연산자는 자바스크립트 변환 시점에서 제거되기 때문 )

 

 

 

4. 구조적 타이핑에 익숙해지기

 

구조적 타이핑을 알아보기 전 우리는 dock typing이 무엇인지 알 필요가 있다.

 


 dock typing?

객체가 어떤 타입에 부합하는 변수와 메서드를 가질 경우 객체를 해당 타입에 속하는 것으로 간주하는 방식

( 명제 :  "만약 어떤 새가 오래처럼 걷고 헤엄치고 소리를 낸다면 나는 그 새를 오리라고 부를 것" )

 

Structural Typing ?

- 실제 구조와 정의에 의해 결정되는 타입 시스템의 한 종류

 

interface Vector2D {
  x: number
  y: number
}
interface NamedVector {
  name: string
  x: number
  y: number
}
function calculateLength(v: Vector2D) {
  return Math.sqrt(v.x * v.x + v.y * v.y)
}
const v: NamedVector = { x: 3, y: 4, name: 'mgh' }
calculateLength(v)

 

Vector2D와 NamedVector의 관계를 선언하지 않았다.

또한 NamedVector를 위한 별도의 calculateLength를 구현할 필요도 없다.

즉, NamedVector의 구조가 Vector2D와 호환되기때문에 calculateLength를 호출이 가능하다.

여기서 '구조적 타이핑' 이라는 용어가 사용된다.

 

즉, 구조적 타이핑에서는 명목적 타이핑과 같은 명확한 상속관계를 지향하기보단 집합으로 포함한다는 개념을 지향하기 때문에 Vector2D의 속성에 해당하는 값이 값을 넣는 타입에 속성으로 존재하는가로 접근하여 이해해야 한다.

 

 

정리

- 자바스크립트가 dock typing 기반이고 타입스크립트가 이를 모델링 하기 위해 구조적 타이핑을 사용

 

- class 역시 구조적 타이핑 규칙을 따름 ( 클래스의 인스턴스가 예상과 다를 수 있다.)

 

- 구조적 타이핑을 이용하면 unit test를 쉽게 할 수 있다.

 

 

 더 자세한 내용 참고 :https://vallista.kr/%EB%8D%95-%ED%83%80%EC%9D%B4%ED%95%91%EA%B3%BC-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%83%80%EC%9D%B4%ED%95%91/

 

 

5.  Any타입 지양하기

사실 타입스크립트를 잘 알지 못하는 상태에서도 너무 유명한 사진이 있었다. 

any 남발중.. ^^

any를 사용하여 에러를 없애고 유연하게 코드를 짜고 싶다고 생각할 수도 있다.

하지만 타입스크립트에서는 any타입을 지양한다.

 

그 이유에 대해 알아보자.

 

1) any타입은 안전성이 없다

 

2) any는 함수 시그니처를 무시해버린다.

 

3) any타입에는 언어 서비스(자동완성 기능과 적절한 도움말) 가 적용되지 않는다. 

 

4) any타입은 코드 리팩터링 때 버그를 감춘다.

 

5) any타입은 타입 설계를 감춘다.

 

6) any는 타입시스템의 신뢰도를 떨어뜨린다.

 

위와 같은 이유로 any타입을 최대한 지양하지만, js에서 마이그레이션을 하는경우는 any타입 설정부터 시작하는것은 괜찮다고 한다.

 

 


지금까지 타입스크립트란 무엇인가에 대해 알아보았다.

다음글은 타입스크립트의 타입시스템에 대해 알아보겠다! 

'FE > TypeScript' 카테고리의 다른 글

[TypeScript] keyof와 typeof란 ?  (0) 2023.03.01
[TpyeScript] 타입스크립트과 의존성 (@types)  (0) 2022.10.06