종종 실제 타입이 컴파일러가 추론한 타입보다 구체적인 상황이 발생합니다.
이러한 상황에서 타입 단언을 쓰면 컴파일러에게 특정 타입을 단언할 수 있습니다.
타입 단언 (Type Assertion)
종종 컴파일러보다 개발자가 타입을 더 잘 알 때가 있습니다.
주로 데이터의 실제 타입이 컴파일러가 추론한 타입보다 구체적인 상황이 됩니다.
타입 단언은 컴파일러에게 특정 타입을 명시적으로 단언하는 개념입니다.
타입 단언은 런타임에 영향을 미치지 않습니다.
즉 특별한 검사나 데이터의 재구성이 발생하지 않습니다.
그저 타입 체커의 에러를 없애기 위해 컴파일 과정에서 사용하는 문법입니다.
let a;
a = 20;
a = 'hello';
let b = a; // b: any
let b = a as string; // b: string
예시를 보면 a에 마지막으로 문자열 값을 할당했지만 a는 여전히 Any 타입입니다.
그래서 b 또한 Any 타입으로 취급됩니다.
이때 타입 단언을 사용하여 b가 String 타입을 갖게 할 수 있습니다.
타입 단언 방법
타입을 단언하는 방법은 2가지가 있습니다.
1. as 키워드
let str: unknown = "this is a string";
let strLength: number = (someValue as string).length;
JSX에서는 as 키워드로만 타입 단언이 가능합니다.
2. 앵글 브라켓 (angle-bracket, < >)
let str: unknown = "this is a string";
let strLength: number = (<string>someValue).length;
이 방식은 JSX(.tsx)에서 사용할 수 없습니다.
JSX 태그와 혼동되어 파싱에 문제가 발생할 수 있기 때문입니다.
타입 선언 vs 타입 단언
type Person = { name: string };
const alice: Person = { name: 'Alice' };
const bob = { name: 'Bob' } as Person;
TypeScript에서 타입을 부여하는 방법은 두 가지가 있습니다.
타입 선언은 할당된 값이 타입, 인터페이스를 만족하지 않으면 에러를 발생시킵니다.
타입 단언은 그저 타입 체커가 발생시킨 오류를 무시하도록 만들어줍니다.
결론적으로 타입 선언이 타입 단언보다 안전합니다.
const button = document.querySelector('button'); // type: HTMLButtonElement | null
const buttonText = button.innerText // Object is possibly 'null'
// 타입 단언 - 1. as
const button = document.querySelector('button') as HTMLButtonElement; // type: HTMLButtonElement
// 타입 단언 - 2. Non-null assertion operator
const button = document.querySelector('button')!; // type: HTMLButtonElement
const buttonText = button.innerText // OK
다만 예외적으로 DOM 접근에 있어서는 타입 단언이 자주 사용됩니다.
null로 추정될 가능성이 있다면 DOM 메서드를 사용할 때 오류가 발생하기 때문입니다.
🔎 Non-null 단언 연산자 (Non-null assertion operator)
const button = document.querySelector('button')!; // type: HTMLButtonElement
값 뒤에 느낌표(!) 연산자가 붙으면 해당 피연산자가 null, undefined가 아님을 단언할 수 있습니다.
주로 DOM 접근 등에 있어 null 추정으로 인한 오류를 방지하기 위해 사용합니다.
다만 그 값이 null이 아님을 확신할 수 있을 때 사용해야 합니다.
'프론트엔드 > TypeScript' 카테고리의 다른 글
[TypeScript] 유틸리티 타입 구현하기 (Utility Types) (0) | 2022.06.07 |
---|---|
[TypeScript] 제네릭 (Generic) (0) | 2022.06.07 |
[TypeScript] Interface와 Type Alias의 차이점 (0) | 2022.06.06 |
[TypeScript] 타입 가드 (Type Guard) (0) | 2022.06.02 |
[TypeScript] 타입 종류 (0) | 2022.05.31 |