[TypeScript] 타입 단언

종현·2024년 1월 2일

[TypeScript]

목록 보기
11/19

타입 단언이란?

  • 타입스크립트가 해주는 타입 추론에 기대지 않고, 개발자가 직접 타입을 명시하여 해당 타입으로 강제하는 것을 의미한다.

  • as라는 키워드를 사용하여 타입을 단언할 수 있다.

  • as 키워드를 붙이면 타입스크립트가 컴파일할 때 해당 코드의 타입 검사는 수행하지 않는다.

  • as 또는 ! 키워드를 사용하여 타입 단언을 할 수 있지만 단순히 편리함 때문에 사용하게되면 예상치 못한 에러가 코드의 실행 시점에서 발생할 수 있기 때문에 가급적이면 타입 추론에 의지하는 것이 좋다.

interface Person {
  name: string;
  age: number;
}

const me = {};
/** 아래 두 줄의 me객체의 속성을 추가하는 코드에서는 에러가 발생하는데
*   me객체는 빈 객체로 초기화 되어 타입스크립트의 입장에서는 타입을 추론할 수 없기 때문에
*   '{}'형식에 'name' 속성이 없습니다. 라는 에러가 발생한다.

*   이를 해결하기 위해 빈 객체가 아닌 아래 속성이 들어있는 상태로 초기화를 하거나
*   const me: Person = ... 같은 형식으로 타입을 정해줄 수 있지만, 

*   이미 서비스가 진행되고있고, 누군가가 만들어 놓은 코드라고 한다면 이로 인해 변경하거나 
*   발생하는 문제들이 생길 수 있기 때문에 "const me = {} as Person"으로 에러를 해결할 수 있다.
*/
me.name = 'jonghyun';
me.age = 99;

타입 단언 문법

타입 단언의 대상

  • 숫자, 문자열, 객체 등 원시 값뿐만 아니라 변수나 함수의 호출 결과에도 사용할 수 있다.

타입 단언 중첩

const me = ('jonghyun' as any) as string;

// 위의 코드는 아래 코드의 순서대로 타입이 정의된다.
const me = 'jonghyun' as any;

const me = 'jonghyun' as string;

주의할 점

  • as 키워드는 구문 오른쪽에서만 사용한다.

    • 타입 단언은 변수 이름에 사용할 수 없다.
const num as number = 10; // 이 코드는 에러가 발생한다.
                          
const num = 10 as number; // 위의 코드 대신 이 코드를 사용해야 한다.

const num: number = 10;   // 위의 코드 보다는 이 코드처럼 타입을 표기하여 정의하는 것이 좋다.
  • 호환되지 않는 데이터 타입으로는 단언할 수 없다.

    • 아래 코드처럼 타입이 string인 변수의 타입을 number로 단언한다고 해서 타입이 number로 변경되지 않고 에러가 발생한다.
/** 
*   Conversion of type 'string' to type 'number' may be a mistake because 
*   neither type sufficiently overlaps with the other. If this was intentional, 
*   convert the expression to 'unknown' first.
*/
const me = 'jonghyun' as number; 

타입 단언 남용하지 않기

  • 타입스크립트에 익숙하지 않을 때 타입 단언이 주는 편리함에 취할 수 있다.

  • 하지만 타입 단언은 코드를 실행하는 시점에서 아무런 역할도 하지 않기 때문에 에러에 취약하다.

  • 타입 단언을 사용하여 당장 눈에 보이는 에러를 안보이게 할 수 있지만 타입스크립트의 목적과 장점인 실행 시점의 에러를 예측하고 알아낼 수 없다.

null 아님 보장 연산자 : !

  • ! 키워드는 null 타입을 체크할 때 쓰이는 연산자이다.

  • as 키워드와는 다르게 값이 null이 아님을 보장해 준다.

  • 타입스크립트의 타입 체크 레벨을 엄격모드로 바꾸면 꽤 많은 웹 API가 null을 반환한다.

  • 그러므로 아래 코드처럼 함수안에서 파라미터가 null이라면 함수를 종료해주는 로직을 추가해주어야 하는데 이 과정이 번거롭고 null이 아니라는 확싱이 있다면 !연산자를 사용하여 단언을 해줄 수 있다.

interface Books {
  shuffle: Function
}

function shuffleBooks(books: Books | null) {
  const result = books!.shuffle();
  
  return result;
}

출처: 쉽게 시작하는 타입스크립트

profile
지속 가능한 성장 습관을 만들어 나가고 싶어요!

0개의 댓글