[TypeScript] 타입 추론, 타입 및 할당 단언, 타입 가드
타입 추론 (Inference)
추론 : 판단을 근거로 삼아 다른 판단을 이끌어 냄
모든 부분에 타입을 직접 지정할 필요는 없고, 꼭 필요한 부분에 타입을 지정해준다.
타입을 추론하기 위해서는 근거로 삼을 수 있는 판단이 필요하다.
초기화된 변수
let num = 12
기본값이 설정된 매개 변수, 반환 값이 있는 함수
function add(a: number, b = 2) {
return a + b
}
숫자 데이터가 기본적으로 할당되므로, b에는 타입을 지정해주지 않아도 된다.
a,b 가 number 타입이므로, 반환 타입을 따로 지정하지 않아도 타입 추론이 가능하다.
👉 최대한 타입을 적게 적으면서 타입스크립트가 이해하지 못하는 곳에는 꼭 정확한 타입을 제공해주어야 한다.
타입 단언 (Assertions)
단언 : 주저하지 아니하고 딱 잘라 말함
- 단원 키워드 - as
- Non-null 단언 연산자 - !
예시 1
const el = document.querySelector('body') as HTMLBodyElement
el.textContent = 'Hello world';
const els = document.querySelector('body')
els!.textContent = 'Hello world';
단언 키워드 as를 사용하지 않으면 el 의 타입이 HTMLBodyElement | null 로 추론된다.
하지만 개발자는 body 태그가 null이 아닐 것이라는 확신이 있으므로 HTMLBodyElement 타입을 단언한다.
- as 키워드를 선언해서 타입을 단언한다.
- 단언 연산자 ! 를 사용해서 null이 아니라고 단언한다.
예시 2 (잘못된 타입단언)
function getNumber(x: number | null | undefined) {
// return Number(x.toFixed(2)) --> error
return Number((x as number).toFixed(2))
}
getNumber(3.1415)
getNumber(null) // error
null, undefined 타입은 toFixed 메서드를 사용할 수 없으므로 타입 에러가 발생한다.
위 코드처럼 매개 변수 x에 타입단언을 하면 코드의 에러는 사라지지만, 실제로 동작하며 null 데이터가 들어온다면 에러가 발생한다.
예시 3
function getValue(x: string | number, isNumber: boolean) {
if (isNumber) {
return Number(x.toFixed(2))
}
return x.toUpperCase()
}
위의 코드에서 x가 string이나 number 타입인데, 두 개의 타입 모두에서 toUpperCase 메서드를 사용할 수 없다는 에러가 발생한다.
function getValue(x: string | number, isNumber: boolean) {
if (isNumber) {
return Number((x as number).toFixed(2))
}
return (x as string).toUpperCase()
}
getValue('hello world', false) // 'HELLO WORLD'
getValue(3.1415, true) // 3.14
개발자들이 알 수 있는 문법을 통해 작성된 코드가 있을 때 ts가 코드의 내용을 추론하지 못한다면
개발자가 코드의 내용을 확신할 때 타입을 단언해준다.
할당 단언 ( Assertion)
let num!: number
console.log(num)
num = 123
num 을 초기에 단언해주지 않는다면 콘솔을 찍을 때 num 변수에 값이 할당되지 않으므로 에러가 발생한다.
number 타입이 지정될 때 할당을 했다는 뜻으로 초기에 단언을 해주면서 코드 에러를 없앨 수 있다.
타입 가드 (Guards)
if 조건이나 기타 다양한 내용들을 통해 작성된 코드가 실제로 잘 동작할 수 있도록 코드 상에서 방어를 한다.
예제 1
function logText(el: Element) {
console.log(el.textContent)
}
const h1El = document.querySelector('h1') as HTMLHeadingElement
logText(h1El)
ts 코드 에러를 막기 위해 HTMLHeadingElement로 타입 단언을 해줬지만,
실제 동작에서 화면에 h1 요소가 없다면 null이 출력되며 에러가 발생한다.
function logText(el: Element) {
console.log(el.textContent)
}
const h1El = document.querySelector('h1') as HTMLHeadingElement
if(h1El) {
logText(h1El)
}
if (h1El instanceof HTMLHeadingElement){
logText(h1El)
}
실제로 그 데이터가 존재할 때만 내용이 동작하게 만들어주는 타입 가드를 사용해서 해결할 수 있다.
if 조건이나 기타 다양한 내용들을 통해 작성된 코드가 실제로 잘 동작할 수 있도록 코드 상에서 방어를 한다.
예제 2
function add(val: string | number){
let res = 'Result => '
if (typeof val === 'number'){
res += val.toFixed(2)
} else {
res += val.toUpperCase()
}
console.log(res)
}
add(3.141592) // 'Result => 3.14'
add('hello world') // 'Result => HELLO WORLD'
👉 자바스크립트에서 중요하게 사용할 수 있는 스킬이며, 에러가 발생할 수 있는 상황 자체를 코드 상에서 방어한다 !