๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
typescript

๐Ÿ– ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ œ๋„ค๋ฆญ

by frontChoi 2025. 2. 7.
๋ฐ˜์‘ํ˜•

๐Ÿž ์ œ๋„ค๋ฆญ์ด ๋ฌด์—‡์ธ๊ฐ€

์ œ๋„ค๋ฆญ์€ ๋‹ค์–‘ํ•œ ํƒ€์ž…์„ ํ—ˆ์šฉํ•จ์œผ๋กœ์จ, ์žฌํ™œ์šฉํ•˜๋Š”๋ฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ด๋‹ค

 

๐Ÿฅ— ์ œ๋„ค๋ฆญ ์‚ฌ์šฉ์˜ˆ์‹œ

์ค‘๋ณต์ด ๋˜๋Š” ๊ฒฝ์šฐ

/*
์ค‘๋ณต์ด๋˜๋Š” ๊ฒฝ์šฐ
*/
// Person1๊ณผ Person2์˜ ๊ฒฝ์šฐ name,age ์ œ์™ธํ•˜๊ณ  ๊ฐ’์ด ๋˜‘๊ฐ™๋‹ค
interface Person1 {
  type: "human";
  race: "yello";
  name: "TEST1";
  age: 32;
}

interface Person2 {
  type: "human";
  race: "yello";
  name: "TEST2";
  age: 28;
}

//์ œ๋„ค๋ฆญ์„ ํ†ตํ•ด ์ค‘๋ณต ์ œ๊ฑฐ
interface PersonGenric<N, A> {
  type: "human";
  race: "yello";
  name: N;
  age: A;
}
interface Person3 extends PersonGenric<"choi", 32> {}
interface Person4 extends PersonGenric<"choi2", 28> {}

ํ•จ์ˆ˜ ํ‘œํ˜„์‹,์„ ์–ธ๋ฌธ

/*
ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ,ํ‘œํ˜„์‹
*/
//ํ•จ์ˆ˜ ํ‘œํ˜„์‹
const personFactoryE = <N, A>(name: N, age: A) => ({
  type: "human",
  race: "yellow",
  name,
  age,
});

//ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ
function personFactoryD<N, A>(name: N, age: A) {
  return {
    type: "human",
    race: "yellow",
    name,
    age,
  };
}

const p0 = personFactoryE<string,number>("choi",32)
//ํƒ€์ž…์ถ”๋ก ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค
const p1 = personFactoryE("choi", 32)
const p2 = personFactoryD("choi1", 33);

ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ

/*
ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
*/
class Person<N, A> {
  name: N;
  age: A;
  constructor(name: N, age: A) {
    this.name = name;
    this.age = age;
  }
  method<B>(param: B) {}
}


const classP = new Person<string, number>("choi", 32);
classP.method<string>("1")

 

Promise ์ œ๋„ค๋ฆญ

interface Data<T>{
	resultCd: string,
	data:T
}

interface Response<T>{
	status: number,
	data:Data<T>
}

interface ResultData{
	list:string[]
}

function fn() {
	return new Promise<Response<ResultData>>((reolve) => reolve({
		// Response Interface (status:number,data:Data<T>) 
		status: 200,
		// Data Interface (resultCd:string,data:T) 
		data: {
			resultCd: '0000',
			// ResultData Interface (list:string[])
			data: {
				list:['1']
			}
		}
	}))
}

 

 

โ˜•๏ธ react + typescript์—์„œ ์ œ๋„ค๋ฆญ ์‚ฌ์šฉ 

Response<T>์œผ๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ,  T์˜ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ๋Š” T์˜ Data ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋“ค์–ด๊ฐ€๋„๋ก ํ•˜์˜€๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์— ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ™•์žฅ์„ฑ์— ์šฉ์ดํ•˜๋‹ค

// loginApi.ts


// Response ์ œ๋„ค๋ฆญ
interface Response<T> {
  status: number
  data: T
}

// ์ œ๋„ค๋ฆญ ํƒ€์ž…์— ์“ฐ์ผ ์ธํ„ฐํŽ˜์ด์Šค
interface Data {
  resultCd: string
  resultMsg: string
}

// ๋กœ๊ทธ์ธ ์š”์ฒญ ํƒ€์ž…
interface LoginRequest {
  id: string
  pw: string
}

// Promise์—์„œ returnํ• ๋•Œ Responseํ˜•ํƒœ๋กœ ๋ฆฌํ„ด ๋˜๋ฉฐ, ๊ทธ ์ค‘์— Response<T>์˜ T์˜ ๋งคํ•‘๋˜๋Š”๊ฒƒ์ด 
// Data ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค 
const loginApi = (param: LoginRequest): Promise<Response<Data>> => {
  const successMsg: Data = {
    resultCd: '0000',
    resultMsg: '๋กœ๊ทธ์ธ์„ฑ๊ณต',
  }

  const failMsg: Data = {
    resultCd: '0001',
    resultMsg: '๋กœ๊ทธ์ธ์‹คํŒจ',
  }

  return Promise.resolve({
    status: 200,
    data: param.id === 'chleorjs37@gmail.com' && param.pw === 'chleorjs12@' ? successMsg : failMsg,
  })
}

export { loginApi }

 

ํ™”๋ฉด์—์„œ loginApiํ˜ธ์ถœ์„ ํ†ตํ•ด vscode์—์„œ res์˜ ํƒ€์ž…์„ ๋ฏธ๋ฆฌ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Response<Data>์œผ๋กœ ์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ,

์ž‘์—…ํ•˜๋Š”๋ฐ ๊ต‰์žฅํžˆ ์œ ์šฉํ•˜๋‹ค

/* eslint-disable arrow-parens */
import * as styles from './login.module.css'
import Input from '../../components/common/Input/Input'
import Button from '../../components/common/Button/Button'
import { loginApi } from '../../service/api/loginApi'
import { useState } from 'react'
function Login() {
  const [userInfo, setUserInfo] = useState({
    id: '',
    pw: '',
  })

  function isValidation() {
    if (!userInfo.id || !userInfo.pw) return false

    return true
  }

  function idInputChangeEvent(text: string) {
    setUserInfo({
      ...userInfo,
      id: text,
    })
  }
  function pwInputChangeEvent(text: string) {
    setUserInfo({
      ...userInfo,
      pw: text,
    })
  }

  function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    if (!isValidation()) {
      alert(`์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”`)
      return
    }
    const param = {
      id: userInfo.id,
      pw: userInfo.pw,
    }
    // ๋กœ๊ทธ์ธ Api์˜ res์˜ ํƒ€์ž…์ด ์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. Response<Data>์ด๋‹ค
    loginApi(param).then((res) => {
      // Response์˜ ํƒ€์ž…์ด๋‹ค. status:number, data:Data
      const { status, data } = res
      if (status === 200) {
	      // Data์˜ ํ˜•ํƒœ์ด๋‹ค. resultCd,resultMsg
        const { resultCd, resultMsg } = data
        if (resultCd === '0000') {
          alert(resultMsg)
        } else {
          alert(resultMsg)
        }
      }
    })
  }

  return (
    <div className={styles.login_form_container}>
      <form className={styles.login_form} onSubmit={onSubmit}>
        <h1 className={styles.login_title}>{'๋กœ๊ทธ์ธ'}</h1>
        <div className={styles.form_group}>
          <label className={styles.form_label}>{'ID'}</label>
          <Input placeholder={'ID๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'} changeEvent={idInputChangeEvent} />
        </div>

        <div className={styles.form_group}>
          <label className={styles.form_label}>{'PW'}</label>
          <Input placeholder={'PW๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”'} inputype={'password'} changeEvent={pwInputChangeEvent} />
        </div>

        <div className={styles.form_btngroup}>
          <Button buttontype={'submit'} buttonname={'๋กœ๊ทธ์ธ'} />
        </div>
      </form>
    </div>
  )
}

export default Login
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€