타입체커는 선언된 타입이 해당 인터페이스를 만족하는지 검사한다. 하지만 타입 단언은 강제로 타입을 지정하여 타입체커가 오류를 무시하도록 한다. 따라서 꼭 필요한 경우에만 사용해야한다
화살표 함수에서 반환되는 값의 타입이 모호할 때가 있다.
interface Station {
name: string
}
const stations = ['정자', '미금'].map(name => ({name}))
// typeof locations === {name: string}[]
이런 경우 종종 아래처럼 타입 단언을 사용하여 해결한다.
const stations = ['정자', '미금'].map(name => ({name} as Station)) // Station[]
하지만 타입단언은, 타입체커가 화살표함수의 반환 타입을 검증하지 않도록 하기 때문에 좋은 방법은 아니다. 보다 자연스러운 방법은 화살표 함수의 반환 타입을 선언하는 것이다.
const stations = ['정자', '미금'].map((name):Station => ({name})) // Station[]
타입체커가 추론하는 값보다 내가 선언하는 타입이 더 정확할 때 사용한다.
document.getElementById('button').addEventListener('click', e => {
const button = e.currentTarget // typeof button === EventTarget | null
console.log(button.tagName)
})
위 코드의 경우 타입스크립트는 DOM에 접근할 수 없기 때문에 버튼엘리먼트인지 알 수 없다. 이런 경우 타입단언을 쓰는 것이 적절하다.
단언될 수 있는 타입은, 덜 구체적(슈퍼)이거나 더 구체적인(서브) 클래스이다. 이는 불가능한 강제변환을 막기 위함이다.
interface Person {
name: string
}
const body = document.body as Person // type Error
만약 꼭 임의의 타입으로 강제변환해야 한다면 모든 타입의 슈퍼 클래스인 unknown
로 변환하고, 다시 임의의 클래스로 변환한다.
const body = document.body as unknown as Person
이는 unknown
타입을 사용한 이상 위험한 동작을 하고 있다는 걸 알 수 있게 한다.