TypeScript 공부(3)

김희목·2024년 8월 24일
0

패스트캠퍼스

목록 보기
46/53

타입 추론(Inference)

'추론' = 어떠한 판단을 근거로 삼아 다른 판단을 이끌어 냄.

1) 초기화된 변수
2) 기본값이 설정된 매개 변수
3) 반환 값이 있는 함수

let num = 12
num = 'Hello type!'

타입스크립트가 타입 추론을 통해 num이 어떤 타입인지 작성해주지 않아도 number라는 타입으로 인식을 하고, 그아래 코드에서 문자형으로 새롭게 초기화를 해줘도, 타입 오류가 발생됩니다.

즉, 우리는 타입스크립트가 추론하지 못하는 곳에서만 타입을 지정해주면 됩니다.

이번에는 위에 3가지 예시로 된 상황들을 보면서 확인해보겠습니다.

// 초기화 된 변수 `num`
let num = 12

// 기본값이 지정된 매개 변수 `b` + 반환 값이 확실한 함수 `add`
function add(a: number, b: number = 2): number {
	return a+b
}

초기화 된 변수 num처럼 타입이 명확한 특정 데이터를 할당하면 타입스크립트는 추론을 통해 숫자 데이터로 인식을 할 수 있습니다.

함수 b를 보면, b: number = 2 처럼 기본값이 지정되어 있는데 이러한 경우에도 우리는 추론을 통해 b는 number라는 타입을 추론할 수 있습니다. 그래서 해당 코드를 b=2 로 작성을하여도 우리는 b가 number 타입이라는 것을 확인할 수 있습니다.

add의 결과 값도 number로 지정해주지 않아도 됩니다. 그 이유는 a의 값도 Number, b의 값도 Number 이라면, 해당 return의 값도 Number 이기 때문에, 해당 타입도 설정해주지 않아도 타입스크립트에서는 추론을 통해 해당 값의 리턴값이 숫자형이라는 것을 알 수 있습니다.

function add(a: number, b = 2) {
	return a + b
}

위의 코드처럼 작성해 줄 수 있습니다.

타입 단언(Assertion)

'단언' - 주저하지 아니하고 딱 잘라 말함.

단언 키워드 - as
Non-null 단언 연산자 - !

1)

const el = document.querySelector('body')
el.textContent = 'Hello world?!'

여기서 el.textContent 부분에서 el에 타입 오류가 나는데, 그 이유는 el이 null일 수 있기 때문입니다.

el이 null이 될 수 있는 이유는 document.querySelector('body')가 HTML 문서에서 body 요소를 찾지 못할 가능성이 있기 때문입니다.

예를 들어, JavaScript 코드가 실행될 때 아직 DOM 트리가 완전히 로드되지 않은 경우, 즉 body 요소가 아직 생성되지 않았을 때 이 코드가 실행되면 document.querySelector('body')는 null을 반환하게 됩니다.

이 상황에서 el.textContent = 'Hello world?!';를 실행하면 el이 null이기 때문에, null 객체에서 textContent 속성에 접근하려고 하면 "Cannot set property 'textContent' of null"와 같은 오류가 발생하게 됩니다.

하지만 우리 개발자들은 html 요소의 body태그가 있다는 것을 알고 있습니다. 이러한 경우에 우리는 타입을 단언하여, 문제를 해결할 수 있습니다.

위의 작성되어 있는 as라는 키워드를 사용하는 것입니다. 즉, body 태그는 null 데이터가 아니다 라고 단언을 해주면 됩니다.

const el = document.querySelector('body') as HTMLBodyElement
el.textContent = 'Hello world?!'

즉, html의 body element라는 html의 요소 타입이다 라고, 단언을 해주는 겁니다.

2)

function getNumber(x: number | null | undefined) {
	return Number(x.toFixed(2))
}
getNumber(3.1415926535)
getNumber(null)

해당 코드도 마찬가지로, x.toFixed 부분이 오류가 발생하는데 현재 유니온타입으로, number,null,undefined 세 타입으로 x를 지정해줬는데, toFixed의 경우 숫자형 타입에서만 사용이 가능하기 때문에 오류가 발생했습니다.

이러한 부분을 해결하기 위해 마찬가지로 타입 단언을 통해 해결해 줄 수 있습니다.

function getNumber(x: number | null | undefined) {
	return Number((x as number).toFixed(2))
}
getNumber(3.1415926535)
getNumber(null)

하지만 해당 코드는 당장의 문제를 해결했지만 잘못된 코드입니다.

function getNumber(x: number | null | undefined) {
	return Number(x!.toFixed(2))
}
getNumber(3.1415926535)
getNumber(null)

코드에서 x!를 사용해야 하는 이유는 TypeScript의 non-null assertion operator(!)를 통해 null 또는 undefined일 가능성이 있는 변수에 대해 컴파일러에게 이 변수가 null이나 undefined가 아님을 확신시킬 수 있기 때문입니다.

주어진 코드에서 x의 타입은 number | null | undefined로 지정되어 있습니다. 이 경우 TypeScript는 x가 null이나 undefined일 가능성을 고려해, x를 number로 강제 캐스팅하는 (x as number) 표현에 대해 경고를 줄 수 있습니다. 만약 x가 실제로 null이나 undefined일 경우, .toFixed(2) 메서드를 호출할 때 오류가 발생되기 때문에 이러한 방식보다는 x!를 사용하는 코드가 더 좋습니다.

3)

function getValue(x: string | number, isNumber: boolean) {
	if (isNumber) {
    	return Number(x.toFixed(2))
    }
    return x.toUpperCase()
}
getValue('hello world', false) // 'HELLO WORLD'
getValue(3.1415926535, true) // 3.14

위의 2가지 해결방안을 보고 3번 문제를 해결해보면

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);
getValue(3.1415926535, true);

0개의 댓글