윤시의 블로그

[TypeScript] 타입 추론, 타입 단언, 타입 가드, 타입 좁히기(Narrowing) 본문

TypeScript

[TypeScript] 타입 추론, 타입 단언, 타입 가드, 타입 좁히기(Narrowing)

yo09 2025. 3. 23. 09:41

TS - 타입 추론 (Type Inference)

  • 타입 추론(Type Inference)
  • ⇒ TypeScript에서 코드를 작성할 때 명시적으로 타입을 지정하지 않아도, 컴파일러가 자동으로 변수나 함수의 타입을 추론하는 기능임. 이는 코드를 더 간결하게 작성할 수 있도록 도와줌.

예시

let username = "John"; // string으로 추론
let age = 30; // number로 추론
let isStudent = true; // boolean으로 추론
let list = [1, 2, 3]; // number 배열로 추론

 

함수 반환 타입 추론

함수의 반환값도 컴파일러가 자동으로 타입을 추론함.

function add(a: number, b: number) {
  return a + b; // 반환값을 number로 추론
}

let result = add(3, 5); // result는 number 타입

 

제네릭 활용 시 타입 추론

제네릭을 사용할 경우, 전달된 값에 따라 반환 타입이 추론됨.

function getValue<T>(value: T): T {
  return value;
}

const result1 = getValue(100); // number로 추론
const result2 = getValue("test"); // string으로 추론

 

적절한 타입 추론 사용 예시

기본형 변수나 객체 초기화 시 타입 추론을 활용하는 것이 좋음.

let username = "John"; // string으로 추론
let list = [1, 2, 3]; // number 배열로 추론

const person = {
  name: "Tom", // string으로 추론
  age: 31,     // number로 추론
};

 

주의 사항

any 타입은 타입 추론에서 제외하는 것이 좋음.

let anyVar; // any로 추론됨 → 피해야 함
anyVar = 10;
anyVar = "string";

TS - 타입 단언 (Type Assertion)

  • 타입 단언(Type Assertion)
  • ⇒ TypeScript에서 개발자가 특정 값의 타입을 강제로 지정하는 방법임. 컴파일러가 타입을 추론하지 않고, 개발자가 명시한 타입으로 간주함.

사용 방법

  1. as 키워드 사용 (권장)
let value: any = "Hello, TypeScript!";
let length: number = (**value as string**).length; // string으로 간주
  1. <> 기호 사용 (비권장) JSX와 충돌 가능성이 있기 때문에 권장하지 않음.
let length: number = (<string>value).length; // string으로 간주

 

예시

interface User {
  name: string;
  age: number;
}

// 빈 객체를 User 타입으로 단언
const user = {} **as** User;
user.name = "Tom";
user.age = 25;

 

주의 사항

타입 단언은 런타임 오류를 방지하지 못함. 잘못된 단언을 사용할 경우, 런타임 에러가 발생할 수 있음.

let anyValue: any = "Hello";
let numberValue: number = anyValue as number; // 컴파일은 통과하지만 런타임 오류 발생

 

안전한 사용 방법

타입 단언 대신 타입 가드를 활용하여 타입 안정성을 높이는 것이 좋음.


TS - 타입 가드 (Type Guard)

  • 타입 가드(Type Guard)
  • ⇒ 런타임 시 특정 변수의 타입을 확인하고, 조건문을 통해 변수의 타입을 좁히는 방법임. 이를 통해 코드 안정성을 확보할 수 있음.

typeof 연산자

원시 타입(Primitive Type)을 확인할 때 사용.

let value: unknown = "Hello";

if (typeof value === "string") {
  console.log(value.toUpperCase()); // string 타입으로 좁혀짐
} else if (typeof value === "number") {
  console.log(value.toFixed(2)); // number 타입으로 좁혀짐
}

 

instanceof 연산자

객체가 특정 클래스의 인스턴스인지 확인.

instanceof로 부모 클래스가 누군지 검사할 수 있

class Dog {
  bark() {
    console.log("Woof!");
  }
}
class Cat {
  meow() {
    console.log("Meow!");
  }
}

function printAnimal(animal: Dog | Cat) {
  if (animal instanceof Dog) {
    animal.bark(); // Dog 타입으로 좁혀짐
  } else {
    animal.meow(); // Cat 타입으로 좁혀짐
  }
}

 

in 연산자

객체의 속성을 기준으로 타입을 구분.

서로 배타적인 속성을 가져와야 함!!

if (키 값 in object 자료형) ⇒ if (이 파라미터가 a라는 속성을 안에 가지고 있냐)

interface Student {
  name: string;
  grade: string;
}
interface Employee {
  name: string;
  salary: number;
}

function printInfo(person: Student | Employee) {
  if ("grade" in person) {
    console.log(`${person.name} is a student with grade ${person.grade}`);
  } else {
    console.log(`${person.name} is an employee with salary ${person.salary}`);
  }
}

 

사용자 정의 타입 가드

is 키워드를 사용해 타입 가드를 정의.

function isString(value: unknown): value is string {
  return typeof value === "string";
}

function printValue(value: unknown) {
  if (isString(value)) {
    console.log(value.toUpperCase()); // string으로 좁혀짐
  } else {
    console.log("Not a string");
  }
}

 

적절한 타입 가드 사용

타입 가드는 반드시 필요한 경우에만 사용해야 함. 과도한 타입 가드 사용은 코드 복잡성을 증가시킴.


TS - 타입 좁히기 (Type Narrowing)

  • 타입 좁히기(Type Narrowing)
  • ⇒ 유니언 타입을 특정 조건을 통해 더 구체적인 타입으로 좁히는 과정임.

예시

function processValue(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase()); // string으로 좁혀짐
  } else {
    console.log(value.toFixed(2)); // number로 좁혀짐
  }
}

 

클래스 타입 좁히기

클래스 상속 구조를 활용하여 타입을 좁힐 수 있음.

abstract class Animal {
  abstract speak(): void;
}

class Dog extends Animal {
  speak() {
    console.log("Woof!");
  }
}

class Cat extends Animal {
  speak() {
    console.log("Meow!");
  }
}

function makeAnimalSpeak(animal: Animal) {
  animal.speak(); // Animal 타입에서 좁혀짐
}

makeAnimalSpeak(new Dog()); // Woof!
makeAnimalSpeak(new Cat()); // Meow!

literal type이 있으면 narrowing이 쉬움!

 

예제

type Car = {
  wheel : '4개',
  color : string
}
type Bike = {
  wheel : '2개',
  color : string
}

function 함수(x : Car | Bike){
  if (x.wheel === '4개'){
    console.log('the car is ' + x.color)
  } else {
    console.log('the bike is ' + x.color)
  }
}
  • Car와 Bike 모두 배타적인 속성이 없다.
  • 서로 비슷한 object들이 들어와도, literal type으로 narrowing이 가능하다.

요약

  • 타입 추론: 코드를 간결하게 작성할 수 있도록 도와주는 기능.
  • 타입 단언: 개발자가 특정 값의 타입을 강제로 지정하는 방법.
  • 타입 가드: 조건문 등을 통해 변수의 타입을 확인하고 좁히는 방법.
  • 타입 좁히기: 유니언 타입을 더 구체적인 타입으로 좁히는 과정.

'TypeScript' 카테고리의 다른 글

[TypeScript] interface 문법, &(intersection)  (0) 2025.03.03
[TypeScript] 열거형(enum)  (1) 2025.01.07
[TypeScript] 제네릭(Generics) < >  (1) 2025.01.06
[TypeScript] union, any, unknown 타입  (0) 2025.01.05