타입스크립트를 처음 시작할 때 타입 단언방식은 사용하지 말고, 타입 선언 방식만 사용하라고 들었는데 왜 그래야 하는지 궁금해 찾아보고, 정리했다.
타입 지정 방식
타입 지정에는 두 가지 방법이 있다.
설 명 | |
타입 단언 | 선택된 값을 해당 타입으로 간주한다. |
타입 선언 | 선택된 값이 선언된 타입임을 명시한다. |
interface Person {
name: string;
age: number;
gender: boolean;
}
// 타입 단언
const user1 = {
name: 'Conative',
age: 25,
gender: true
} as Person
// 타입 선언
const user2: Person = {
name: 'Contia',
age: 27,
gender: false
}
아래 간단한 예시를 보면 확연한 차이를 알 수 있다. (인터페이스는 위 Person이다.)
const people = [user1, user2, user3];
// 타입 단언 - 반환값이 빈값이여도 Person객체가 된다.
const men1 = people.map((userInfo):Person => (userInfo as Person));
// 타입 선언 - 반환값이 다르면 에러를 뱉어냄.
const men1 = people.map((userInfo):Person => {
const temp: Person = userInfo;
return temp;
});
// === const men1 = people.map((userInfo):Person => (userInfo));
그리고 타입 선언 시에는 괄호가 바깥에 있는지, 안에 있는지 유의해야 한다.
// 파라미터가 Person이라는 뜻이다.
const myFunction = (userInfo:Person) => {
...
}
// 반환 값이 Person 형식이라는 뜻이다.
const myFunction = (userInfo):Person => {
...
}
타입 단언은 그럼 언제 사용할까?
이렇게만 보면, 타입 단언은 타입을 혼란스럽게 만들어 쓰면 좋을 곳이 없어보이는데, 언제 써야 할까?
타입 단언은 Type checker가 추론한 타입보다 코더가 판단하는 타입이 더 정확할 때 사용한다.
타입 체커가 추론하는 타입보다 코더가 판단하는 타입이 더 정확하다는게 언제일까? 바로 DOM 객체에 접근할 때다.
// HTMLDivElement라고 뜨는 btn을 제대로 잡아준다.
const writeBtn = document.getElementById('writeBtn') as HTMLButtonElement;
// Tip
// !을 사용하면 Null일 경우를 배제할 수 있다. (타입 가드 불필요)
const deleteBtn = document.getElementById('deleteBtn')! as HTMLButtonElement;
// 타입 단언은, A가 B의 부분집합일 경우에만 가능하다.
const modifyBtn = document.getElementById('modifyBtn')! as HTMLButtonElement;
modifyBtn as Person; // 에러!!
타입 사용 시 유의 사항
타입스크립트에서 제공하는 타입 선언은 전부 기본형으로 되어있기에, 객체 타입 사용을 금지한다.
// 기본형
const myMsg: string = 'hello?';
// 객체 타입 (사용 금지)
const yourMsg: String = 'world!';