코딩하는라민

[TypeScript] 유니언 타입(Union Type)과 내로잉(narrowing) 본문

Core/TypeScript

[TypeScript] 유니언 타입(Union Type)과 내로잉(narrowing)

코딩하는라민 2023. 5. 25. 19:33
728x90
반응형

[TypeScript] 유니언 타입(Union Type)과 내로잉(narrowing)

 

 

📌 타입스크립트의 추론

  • 유니언(union) : 값에 허용된 타입을 두 개 이상의 가능한 타입으로 확장하는 것
  • 내로잉(narrowing) : 값에 허용된 타입이 하나 이상의 가능한 타입이 되지 않도록 좁히는 것

 

📌 유니온 타입

둘 이상의 타입을 허용하는 타입.

함수 매개변수 또는 반환 타입으로 여러 타입을 허용하고자 할 때 유니언 타입을 사용할 수 있다.

 

function yourMenu(menu: boolean | string) {
  console.log(`menu: ${menu}`);
}

menu 매개변수에는 불린 또는 문자형을 받을 수 있다. 예를 들어 yourMenu(false) 이 될 수도 있고, yourMenu("chocolate") 도 될 수 있다. 둘 다 유효한 호출!

 

📌 내로잉

타입 가드(Type Guard)를 통해 특정 코드 블록 내에서 변수의 타입 범위를 좁히는 과정을 말한다.

조건문 또는 특정 함수를 사용하여 변수의 타입을 추론하고, 해당 타입으로 좁힐 수 있다. 이를 통해 코드에서 더 구체적인 타입 정보를 활용할 수 있다.

일반적으로 유니언 타입을 가진 변수를 다룰 때 내로잉이 많이 사용된다.

 

타입가드를 통해 얻을 수 있는 효과

  • 타입 안정성⬆️
  • 코드의 신뢰성을 개선

 

✏️ 값 할당을 통한 내로잉

변수에 값을 직접 할당하면 변수의 타입을 ‘할당된 값의 타입’으로 좁힌다.

let myType: number | string;

myType = "ramin"; // ✅ 할당 내로잉 작동

myType.toUpperCase(); // Ok: string
myType.toFixed();
// Error : Property 'toFixed' does not exist on type 'string'.

 

✏️ 조건 검사를 통한 내로잉

일반적으로 타입스크립트는 if 문을 통해 변수 값을 좁히는 방법을 사용한다.

function yourMenu(menu: boolean | string) {
  if (menu === "boolean") {
    console.log(`menu : ${menu}`);
  } else {
    console.log(`menu : ${menu}`);
  }
}

 

안전하지 않은 방식
하지만 조건 검사를 통한 내로잉은 typeof를 사용하는 내로잉보다는 조금 더 위험할 수 있다.
이는 올바르게 내로잉할 수 있는 경우에도 조건문이 타입 검사를 충분히 수행하지 못하고 잘못된 내로잉을 할 수 있는 가능성이 있다.
function yourMenu(menu: string | string) {
  if (menu.length) {
    console.log(`menu : ${menu}`);
  } else {
    console.log(`menu : ${menu}`);
  }
}

이는 menu 의 타입이 string 이 아닌 경우 에러를 발생시킬 수 있다. number 타입은 length 속성을 가지고 있지 않다. 따라서 typeof를 사용하는 내로잉은 타입 안정성을 보장하는 좀 더 안전한 방법이다.

 

✏️ typeof 검사를 통한 내로잉

function yourMenu(menu: boolean | string) {
  if (typeof menu === "boolean") {
    console.log(`menu : ${menu}`);
  } else {
    console.log(`menu : ${menu}`);
  }
}

삼항 연산자로도 변경 가능하다.

 

✏️ 참 검사를 통한 내로잉

타입스크립트에서는 잠재적인 값 중 truthy로 확인된 일부에 한해서만 변수의 타입을 좁힐 수 있다.

let name = Math.random() > 0.5
	? "ramin"
	: undefined;

if(name) {
	name.toUpperCase(); // Ok: string
}

name.toUpperCase(); // Error: Object is possibly 'undefined'.

name 은 "ramin" 뿐만 아니라 undefined 가 될 수도 있기 때문에 name.toUpperCase() 는 에러가 발생한다.

 

논리 연산자 &&

타입스크립트에서 논리연산자 &&는 "단축 평가(short-circuit evaluation)"라는 특징을 가지고 있다.

왼쪽 피연산자가 false, null, undefined 0 , NaN, 혹은 빈 문자열('')인 경우 오른쪽 피연산자를 평가하지 않고 바로 왼쪽 피연산자를 반환하는 동작이다.

 

name && name.toUpperCase(); // Ok
  • name 이 존재하지 않는 경우(undefined 또는 null) : name 자체가 반환 / toUpperCase() 는 호출되지 않음
  • name 이 존재하는 경우 : toUpperCase()가 호출되어 대문자로 반환된 문자열을 반환할 것

 

?.(Optional Chaining)

name 이 존재하는 경우에만 toUpperCase 를 호출하고, 그렇지 않으면 undefined 를 반환한다.

name?.toUpperCase(); // Ok

 

 

 


참고 : 러닝 타입스크립트를 읽고, chat GPT 의 도움을 받아 학습한 내용을 간단하게 정리한 내용입니다.
잘못된 부분이나 문제되는 점이 있으면 댓글 부탁드립니다.

 

728x90
반응형