Gwangju-Web-Study / WoowahanTS_Study

✏️우아한 타입스크립트 with 리액트 스터디
6 stars 2 forks source link

3.3.5 맵드 타입의 readonly 수식어의 사용 #17

Closed gwangminjun closed 2 months ago

gwangminjun commented 2 months ago

📝 p 102

❓ 맵드 타입의 readonly 수식어는 해당 변수를 읽기 전용으로 만들어 줄때 사용하는 수식어 입니다. 해당 수식어를 사용해야 하는 상황과 예시를 만들어주세요

BaekWeb commented 2 months ago
// 결제 관련 API 를 사용해야할 상황 일때

// 1. PaymentResponse` 타입 정의 (읽기전용)
type PaymentResponse = {
  readonly transactionId: string;
  readonly amount: number;
  readonly currency: string;
};

// 2.  processPayment 비동기 함수 정의
async function processPayment(): Promise<PaymentResponse> {
  // `fetch` API를 사용하여 결제 API 엔드포인트에 HTTP POST 요청을 보냄
  const response = await fetch("https://api.payment.com/charge", {
    method: "POST",
    body: JSON.stringify({ amount: 100, currency: "USD" }),
  });

  // 응답을 JSON으로 변환하여 반환
  return await response.json();
}

// 3. processPayment 함수 호출
const payment = await processPayment();
hyeonseong2023 commented 2 months ago

Readonly

Type 집합의 모든 프로퍼티읽기 전용(readonly)으로 설정한 타입을 생성합니다. 생성된 타입의 프로퍼티는 재할당될 수 없습니다.

interface Todo {
  title: string;
}

const todo: Readonly<Todo> = {
  title: "Delete inactive users",
};

todo.title = "Hello";
Cannot assign to 'title' because it is a read-only property.

사용 사례

// 함수 매개변수로 객체를 전달할 때, 입력된 객체를 변형하지 않음을 보장하는 경우
function readonlyStudent(student: Readonly<Student>): void {
  console.log(student.name);

  // student.name = "New Name"; // Error: Cannot assign to 'name' because it is a read-only property.
}

readonly 🆚 Readonly

readonly

Readonly<T>

gwangminjun commented 2 months ago

readonly 수식어를 사용해야 하는 상황

  1. 객체의 불변성(immutability)을 유지

    type AppSettings = {
        readonly theme: string;
        readonly version: string;
        readonly isBeta: boolean;
    };
    
    // AppSettings 타입의 객체 생성
    const settings: AppSettings = {
        theme: "dark",
        version: "1.0.0",
        isBeta: false,
    }; 
    
    // 수정 시도 시 컴파일 에러 발생
    settings.theme = "light" // Error 
  2. 데이터의 무결성을 보장

    type UserProfile = {
        readonly id: number;
        readonly name: string;
        readonly email: string;
    };
    
    const user: UserProfile = {
        id: 1,
        name: "minjun",
        email: "minjun@example.com",
    };
    
    // 수정 시도 시 컴파일 에러 발생
    // user.name = "Jane Doe"; // Error
    
  3. 옵셔널과의 혼합 사용예시

    type BasicProfile = {
        username: string;
        age: number;
    };
    
    const profile1: BasicProfile = {
        username: "minjun", // age는 선택적
        age: 28;
    };
    
    // age를 옵셔널로 변환
    type ProfileWithOptionalAge = {
        username: string;
        age?: number;
    };
    
    const profile2: ProfileWithOptionalAge = {
        username: "minjun", // age는 선택적
    };
    
    // 맵드 타입을 사용해 모든 속성을 선택적으로 변환
    type OptionalProfile = {
        [K in keyof BasicProfile]?: BasicProfile[K];
    };
    
    const profile3: OptionalProfile = {
        username: "minjun", // 모든 속성은 선택적
    };
    
    const profile4: OptionalProfile = {}; // 모든 속성을 생략할 수 있음