TypeScript

고급 TypeScript 문법

와이다이어리 2025. 4. 26. 05:11
반응형

1. 제네릭 (Generics)

제네릭은 함수, 클래스, 인터페이스 등을 정의할 때 구체적인 타입을 미리 정의하지 않고 나중에 실제 사용될 때 그 타입을 지정할 수 있게 해줍니다. 즉, 여러 타입에 대해 유연하게 대응할 수 있는 기능

 

function wrap<T>(value: T): T[] {
  return [value];
}

const num = wrap(10);  // [10] - T가 number로 추론
const str = wrap("hi");  // ["hi"] - T가 string으로 추론

 

<T>는 임의의 타입을 의미하며, 함수나 클래스, 인터페이스에 다양하게 사용할 수 있습니다.

 

2. 유틸리티 타입

TypeScript는 이미 자주 쓰이는 패턴을 위한 유틸리티 타입을 기본으로 제공합니다.

1) Partial<T>

객체의 모든 속성을 선택적으로 만듭니다.

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

const user1: Partial<User> = { name: "John" }; // age는 선택적으로 사용

 

2) Required<T>

객체의 모든 속성을 필수로 만듭니다.

const user2: Required<User> = { name: "Jane", age: 25 }; // 필수 속성

 

3) Pick<T, K>

객체에서 특정 속성만 선택해서 새로운 타입을 만듭니다.

type UserInfo = Pick<User, "name">;  // name 속성만 가져옴
const userInfo: UserInfo = { name: "John" };

4) Omit<T, K>

객체에서 특정 속성만 제외한 새로운 타입을 만듭니다.

type UserWithoutAge = Omit<User, "age">;  // age 속성 제외
const userWithoutAge: UserWithoutAge = { name: "John" };
 

5) Readonly<T>

객체의 속성을 읽기 전용으로 만듭니다.

const user3: Readonly<User> = { name: "Doe", age: 30 };
user3.age = 31; // 오류 발생 - 읽기 전용이라 값을 변경할 수 없음

 

3. 타입 좁히기 (Type Narrowing)

타입 좁히기란 조건문이나 타입 가드를 통해 변수의 타입을 더 구체적으로 제한하는 것을 의미합니다. TypeScript는 조건에 맞는 타입을 자동으로 좁혀 주기 때문에 코드의 안전성을 더욱 높여줍니다.

 

function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(id.toUpperCase());  // id가 string 타입임이 보장됨
  } else {
    console.log(id);  // id가 number 타입임이 보장됨
  }
}

 

4. 인터섹션 타입 (&)과 유니언 타입 (|)

타입을 결합하거나 둘 중 하나를 선택하는 방법입니다.

 

1) 인터섹션 타입 (&)

두 가지 타입을 결합하여 두 속성 모두 가진 객체를 만듭니다.

type Admin = { role: string };
type User = { name: string };

type AdminUser = Admin & User;

const adminUser: AdminUser = {
  role: "admin",
  name: "Lee",
};

 

2) 유니언 타입 (|)

두 가지 타입 중 하나의 타입을 선택할 수 있는 타입입니다.

type StringOrNumber = string | number;

let data: StringOrNumber;
data = "Hello";  // 허용됨
data = 123;      // 허용됨

 

5. 조건부 타입 (Conditional Types)

조건부 타입은 타입이 특정 조건을 만족하는지에 따라 다르게 처리할 수 있게 해줍니다. 매우 강력한 기능으로, 복잡한 타입을 유연하게 처리할 수 있습니다.

type IsString<T> = T extends string ? "Yes" : "No";

type A = IsString<"hello">;  // "Yes"
type B = IsString<number>;   // "No"

 

반응형