Gwangju-Web-Study / WoowahanTS_Study

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

3.3.6. 제네릭의 장점을 살려 사용할 수 있는 작성 케이스로는 무엇이 있을까요? #12

Closed fe-Jay closed 2 months ago

fe-Jay commented 2 months ago

📝 115~118p ❓ 3.3.6. 제네릭의 장점을 살려 사용할 수 있는 작성 케이스로는 무엇이 있을까요? 제네릭은 매개변수나 반환값에 다양한 타입을 넣고 싶을 때 사용합니다. 실제 현업에서 제네릭을 효율적으로 활용할 수 있는 상황과 예시 코드를 작성해주세요.

fe-Jay commented 2 months ago

1. API 응답 처리

async function fetchData<T>(url: string): Promise<T> {
  const response = await fetch(url);
  return response.json();
}

type User {
  id: number;
  name: string;
}

// 사용 예
const user = await fetchData<User>('/api/user/1');
console.log(user.name);

2. 컴포넌트 props 타입 정의 (React)

type ButtonProps<T> {
  label: string;
  onClick: (value: T) => void;
  value: T;
}

function Button<T>({ label, onClick, value }: ButtonProps<T>) {
  return (
    <button onClick={() => onClick(value)}>{label}</button>
  );
}

// 사용 예
<Button<string>  /* 제네릭 타입에 string 지정*/
  label="Click me" 
  onClick={(value) => console.log(value)} 
  value="Hello"
/>
gwangminjun commented 2 months ago

JSON 데이터 , XML 데이터 파싱

JSON과XML 데이터를 타입 상관없이 받아서 파싱 핸들러 함수를 통한 처리


import { parseStringPromise } from 'xml2js';

//데이터 타입 선언
enum DataType {
    JSON = 'json',
    XML = 'xml'
}

// 파싱 핸들러 함수
async function parseData<T>(data: string, dataType: DataType): Promise<T> {
    if (dataType === DataType.JSON) {
        return JSON.parse(data) as T;
    } else if (dataType === DataType.XML) {
        const result = await parseStringPromise(data);
        return result as T;
    } else {
        throw new Error("Unsupported data type");
    }
}

// JSON 데이터 예시
const jsonData = `{
    "name": "minjun",
    "age": 28
}`;

// XML 데이터 예시
const xmlData = `
<Person>
    <name>minjun</name>
    <age>28</age>
</Person>
`;

// JSON 데이터 타입
interface PersonJSON {
    name: string;
    age: number;
}

// XML 데이터 타입
// XML은 구조상 동일한 데이터가 들어갈수있기때문에 배열로 처리한다
interface PersonXML {
    Person: {
        name: string[];
        age: string[];
    };
}

// JSON 데이터 파싱
parseData<PersonJSON>(jsonData, DataType.JSON).then(personFromJSON => {
    console.log(personFromJSON.name); // "John"
    console.log(personFromJSON.age);  // 30
});

// XML 데이터 파싱
parseData<PersonXML>(xmlData, DataType.XML).then(personFromXML => {
    console.log(personFromXML.Person.name[0]); // "John"
    console.log(personFromXML.Person.age[0]);  // "30"
});
hyeonseong2023 commented 2 months ago

아이템 처리 로직

// 아이템 인터페이스
interface Item {
    id: string;
    name: string;
    use(): void;
}

// 무기 클래스
class Weapon implements Item {
    constructor(public id: string, public name: string) {}

    use() {
        console.log(`${this.name} equipped.`);
    }
}

// 방어구 클래스
class Armor implements Item {
    constructor(public id: string, public name: string) {}

    use() {
        console.log(`${this.name} equipped.`);
    }
}

// 아이템 관리 클래스
class ItemManager<T extends Item> {
    private items: { [key: string]: T } = {};

    addItem(item: T) {
        this.items[item.id] = item;
    }

    useItem(id: string) {
        const item = this.items[id];
        if (item) {
            item.use();
        } else {
            console.log('Item not found');
        }
    }
}

// 사용 예시
const weaponManager = new ItemManager<Weapon>();
const armorManager = new ItemManager<Armor>();

weaponManager.addItem(new Weapon('weaponNo1', 'Sword'));
armorManager.addItem(new Armor('armorNo1', 'Shield'));

weaponManager.useItem('weaponNo1'); // Sword equipped.
armorManager.useItem('armorNo1');  // Shield equipped.
BaekWeb commented 2 months ago


// 제네릭 타입 정의
interface ApiResponse<T> {
    data: T;
}

// 카페24 데이터 타입 정의
interface Cafe24Product {
    id: number;
    name: string;
    price: number;
}

// 고도몰 데이터 타입 정의
interface GodomallProduct {
    productId: string;
    productName: string;
    productPrice: number;
}

// API를 호출하는 함수 정의
async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
    try {
        const response = await axios.get<ApiResponse<T>>(url);
        return response.data;
    } catch (error) {
        throw new Error(`Failed to fetch data: ${error}`);
    }
}

//  api url
const cafe24ApiUrl = 'https://api.cafe24.com/v2/products';  
const godomallApiUrl = 'https://api.godomall.com/v1/products'; 

// 데이터 출력 함수 정의
async function printData() {
    try {
        // 카페24 API 데이터 가져오기
        const cafe24Response = await fetchData<Cafe24Product[]>(cafe24ApiUrl);
        console.log('Cafe24 Products:', cafe24Response.data);

        // 고도몰 API 데이터 가져오기
        const godomallResponse = await fetchData<GodomallProduct[]>(godomallApiUrl);
        console.log('Godomall Products:', godomallResponse.data);
    } catch (error) {
        console.error('Error:', error);
    }
}

// 데이터 출력 실행
printData();