이번엔 타입 단언(Type Assertion)
에 대해 알아보겠습니다.
단언하다
는 '바른 말을 하다, 주저하지 않고 딱 잘라 말하다'를 의미하는 단어입니다. 그 이름처럼 타입을 딱 정한다라고 생각하고 타입 단언이 무슨 기능인지 알아보도록 하겠습니다.
타입 단언
은 컴파일러에게 해당 값이 특정 타입이라고 지정하는 문법입니다.
이전 포스트들에서 여러 문법과 기능을 하면서 타입스크립트 컴파일러는 어떤 변수나 객체, 함수의 타입을 추론하고 결정한다고 했습니다. 타입 단언
은 컴파일러 대신 프로그래머가 이 값이 어떤 타입인지 알리고 해당 타입으로 취급하게끔 만들어줍니다.
컴파일러의 타입 추론 대신, 프로그래머가 컴파일러에게 지정한 타입으로 생각하게 만드는 기능입니다.
타입스크립트는 아래와 같은 빈 객체 생성을 허용하지 않습니다. 왜냐하면 Student 객체 타입은 id와 name 프로퍼티를 포함한 객체를 Student 타입으로 추론하는데, 빈 객체는 프로퍼티가 없으므로 Student로 판단할 수 없기 때문입니다.
type Student = {
id: number;
name: string;
};
let student: Student = {};
위 상황처럼 빈 객체를 선언하고 싶은경우 타입 단언
을 사용할 수 있습니다. 타입 단언
은 Value as Type
의 형태로 작성합니다.
type Student = {
id: number;
name: string;
};
let student = {} as Student;
이렇게 타입 단언
을 하면 우선은 student가 빈 객체지만 Student
타입으로 취급해라라는 것으로 알리는 기능이기 때문에 타입 오류를 발생시키지 않습니다.
타입 오류의 발생만 막을 뿐이지 다른 컴파일 오류에 대해선 방지하지 못합니다.
타입 단언
은 초과 프로퍼티 검사도 건너뛰게 해줍니다.type Student = { id: number; name: string; }; let student = { id: 01, name: 'Lee', grade: 1, } as Student;
위 코드에서
grade
라는 초과 프로퍼티가 발생했지만 Student 타입으로 단언했기에 초과 프로퍼티 검사 과정에서 문제가 발생하지 않습니다.
Value as Type
의 형태말고<Type>Value
의 형태로도 타입 단언을 정의할 수 있지만jsx
와 같은 일부 언어의 문법과 혼용될 여지가 있기 때문에as
를 사용한 형태를 이용하는 것이 좋습니다.
타입 단언
을 any 타입
으로 수행할 경우 타입 검사를 완전히 건너뛰게 됩니다.
하지만 이는 타입스크립트의 사용 목적중 하나인 타입 검사를 통해 사전에 오류를 방지하는 것에 완벽하게 반하기 때문에 any 타입 단언
은 자제해야합니다.
타입 단언
은 두 가지 조건 중 하나를 만족하는 경우에만 사용할 수 있습니다.
Value as Type
에서
위의 두 경우에서만 타입 단언
이 가능합니다. 예를 들어 number
타입을 정의해놓고 타입 단언으로 string, boolean
같은 타입을 단언하는 것은 불가능합니다.
타입 단언
은 여러 번 겹치게 사용할 수 있습니다. 다중 단언을 통해서 부모 타입이나 자식 타입이 아니어서 단언이 불가능했던 경우를 가능하게 만들 수 있습니다.
let num1 = 123 as string; // number와 string은 부모-자식이 아니므로 단언 불가능!!!
let num2 = 123 as unknown as string;
//let num2 = (123 as unknown) as string; 괄호로 묶으면 보기 좀 더 편해집니다.
위 코드에서 원래 불가능했던 number - string
타입 단언을 두 타입의 공통 자식 타입인 unknown
을 한 번 거치게 단언하게 만들면 타입 단언이 가능한 관계로 만들 수 있습니다.
타입 단언
때는 const
를 타입으로 사용이 가능합니다. 이 const 단언
은 해당 값을 const
로 선언한 것과 동일한 효과를 주게 타입이 변화합니다.
즉, const 선언처럼 읽기만 가능하고 쓰기는 불가능한 타입이 됩니다.
let num = 123 as const;
//const 단언을한 위 코드는 아래 코드와 동일한 효과를 보여줍니다.
let num: 123 = 123;
Non-null assertion operator
라는 것이 존재합니다. 이 연산자는 타입 단언
과 동일한 효과를 줍니다.
Non-null assertion operator
는 어떤 값 뒤에 !
를 붙여서 해당 값이 undefined
나 null
이 아니라고 단언하는 역할을 합니다.
type Student = {
id: number;
name: string;
};
let student: Student = {
id: 000,
};
let nameLength: number = student.name!.length;
!
를 사용하지 않았다면 name
이 존재하지 않는 프로퍼티이므로 undefined나 null로 계산되어 뒤에 따르는 length 프로퍼티의 호출 과정에서 오류를 발생시켰을 것 입니다.