Typescript 1장

황상진·2022년 9월 21일
0

Typescript

목록 보기
1/1

타입스크립트 알아보기

  • 타입스크립트란?
  • 타입스크립트를 어떻게 여겨야하는지
  • 자바스크립트와는 어떤 관계
  • 타입들
  • duck typing

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

  • 타입스크립트는 자바스크립트의 상위 집합이다.
  • 모든 자바스크립트 프로그램은 이미 타입스크립트 프로그램이다.
  • 그러나 반대로, 타입스크립트는 일반적으로 유효한 자바스크립트 프로그램이 아니다.
  • 타입스크립트는 자바스크립트 런타임 동작을 모델링하는 타입 시스템을 가지고 있기 때문에 런타임 오류 발생시키는 코드를 찾아내려고 한다.
  • 타입체커를 통과하면서도 런타임 오류를 발생시키는 코드는 존재한다.
const names = ['Alice', 'Bob'];
console.log(names[2].toUpperCase());

타입스크립트 설정 이해하기

  • 타입스크립트 컴파일러는 언어의 핵심 요소에 영향을 미치는 몇가지 설정을 포함
  • 타입스크립트 설정은 커맨드 라인을 이용하기 보다는 tsconfig.json을 사용하는 것이 좋음
  • 타입스크립트는 타입 정보를 가질 때 가장 효과적이기 때문에, 되도록이면 noImplicitAny를 설정해야 한다.
  • strictNullChecks는 null과 undefined 관련 오류를 잡아내는데 많은 도움이 된다.

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

  • 타입스크립트 컴파일러는 1. 최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랜스파일(translate+compile)하고 2. 코드의 타입 오류를 체크한다. 그런데 이 두 가지는 독립적으로 수행된다.
  • 따라서 타입스크립트 타입은 런타임 동작이나 성능에 영향을 주지 않아, 타입 오류가 존재하여도 코드 생성(컴파일)은 가능하다.
  • 결국 타입스크립트 타입은 런타임에 사용되지 않아, 런타임 타입과 선언된 타입이 다를 수 있다. 이러한 혼란스러운 상황을 피하기 위해서는 일반적으로 태그된 유니온과 속성 체크 방법을 사용하거나, 클래스를 활용하여 타입스크립트 타입과 런타임 값 둘다 제공하는 방법이 있다.

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

덕 타이핑 (duck typing)

  • 함수의 매개변수 값이 모두 제대로 주어진다면, 그 값이 어떻게 만들어졌는지 신경쓰지 않고 사용한다.
    즉 매개변수 값이 요구사항을 만족한다면 타입이 무엇인지 신경쓰지 않는다.
interface Vector2D {
  x: number;
  y: number;
}
function calculateLength(v: Vector2D){
 return Math.sqrt(v.x * v.x + v.y * v.y); 
}

interface NamedVector {
  name: string;
  x: number;
  y: number;
}
const v: NamedVector = { x: 3, y:4, name: 'zee'}
calculateLength(v); // 정상. 5

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

덕 타이핑의 문제

interface Vector3D {
  x: number;
  y: number;
  z: number;
}
function normalize(v: Vector3D){
  const length = calculateLength(v); // Vector2D 가 아닌 Vector3D 타입을 넣어도 오류가 나지 않는다.
  return {
    x: v.x / length,
    y: v.y / length,
    z: v.z / length,
  };
}

normalize({x:3, y:4, z:5}); // { x: 0.6, y: 0.8, z: 1 }

calculateLength 가 2D 벡터를 받도록 선언했지만 3D 벡터를 받는데 문제가 없었다.

Vector3D 구조가 Vector2D 와 호환되기 때문이다.

  • 이런 타입은 '열려(open)'있는 타입이라고 한다.

함수에서 매개변수의 속성들이 매개변수 타입에 선언된 속성만 가지는 경우를 봉인된(sealed), 정확한(precise) 타입이라고 부른다. 열린 타입은 이와 반대이다.

즉 타입에 선언된 속성 외의 다른 속성들을 가지더라도 두 타입은 서로 호환된다.

any 타입 지양하기

  • any 타입은 타입 체커와 타입스크립트 언어 서비스를 무력화 시키기 때문에 지양해야 한다.
let age: number;
age = '12';
// ~~~ Type '"12"' is not assignable to type 'number'
   age = '12' as any;  // OK
age += 1;  // OK; at runtime, age is now "121"

원래 number타입을 any타입으로 바꾸었기 때문에 age는 '12'를 할당받아, string타입으로 바뀌어 age에 1을 더할 때 '121'이 된다!

  • 또한 any 타입은 함수 시그니처를 무시한다. 함수를 호출하는 쪽은 약속된 타입의 입력을 제공하고, 함수는 약속된 타입의 출력을 반환한다. 그러나 any 타입은 이 약속을 어겨 함수의 시그니처를 무시할 수 있다.
function calculateAge(birthDate: Date): number {
  // COMPRESS
  return 0;
  // END
}

let birthDate: any = '1990-01-19';
calculateAge(birthDate);  // OK

이 함수의 시그니처는 매개변수가 Date 타입이어야 한다는 것이다. 하지만 위 코드에서는 any 타입을 사용하여 이 시그니처를 무시한 것이다.

  • 언어 서비스가 제공되지 않는다.

자동완성 기능과 적절한 도움말이 제공되지 않는다.

  • 코드 리팩토링 때 버그를 감춘다.

타입 체커를 통과함에도 런타임에 오류가 발생할 수 있게된다.

  • 타입 설계를 감춘다.

  • 타입 시스템의 신뢰도를 떨어뜨린다.

any 타입으로 인해 런타임에 타입 오류가 발생될 수 있고 이는 신뢰할 수 없는 코드이다.

profile
Web FrontEnd Developer

0개의 댓글