๐Ÿชํƒ€์ž…์Šคํฌ๋ฆฝํŠธ(Typescript)Partial,Pick,Omit

Yewon Jeongยท2023๋…„ 4์›” 2์ผ
0

์Šคํƒ€ํŠธ์—… ํ‡ด์‚ฌ ํ›„, ๋ฐ”๋กœ IT ์—ฐํ•ฉ ๋™์•„๋ฆฌ์ธ DND 8๊ธฐํ™œ๋™์„ ์ง„ํ–‰ํ–ˆ๋‹ค. DND ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชฉ์ ์ธ โ€œ์•ˆ์ •์„ฑโ€๊ณผ ์ด๋ฅผ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•œ ๋ถ€๋ถ„๋“ค์„ ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

์„œ๋น„์Šค URL -> https://www.wise24life.site

๐Ÿ’ปย Web FrontEnd ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์ด์ œ ๋ˆ„๊ตฌ๋‚˜ ์•„๋Š”

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์  ํƒ€์ž… ๋ฌธ๋ฒ•์„ ์ถ”๊ฐ€ํ•œ ์–ธ์–ด์ด๋‹ค. โ€œ์ปดํŒŒ์ผโ€๋‹จ๊ณ„์—์„œ ํƒ€์ž…๊ฒ€์‚ฌ๊ธฐ(Type Checker)๋ฅผ ํ†ตํ•ด ์‚ฌ์ „๊ฒ€์‚ฌ๋ฅผ ํ•˜์—ฌ ๋Ÿฐํƒ€์ž„์— ๋ฐœ์ƒํ•˜๊ฒŒ ๋  ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.(*๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋งŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์— ๋นŒ๋“œ๊ณผ์ •์—์„œ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™˜๋œ๋‹ค. )

๐Ÿ•—ย ์‹œ๊ฐ„์ด ์—†๋‹ค!! ์ผ๋‹จ ๋˜๋Š”๋Œ€๋กœ ๋•Œ๋ ค๋„ฃ์ž!๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜จ ์ฒด๊ณ„์—†๋Š” ์ฝ”๋“œ๋“ค

์‚ฌ์‹ค ๋ฐ”๋กœ ์ง์ „ ์Šคํƒ€ํŠธ์—…์—์„œ ๊ทผ๋ฌดํ•  ๋•Œ๋Š”, ์›น๊ฐœ๋ฐœ์„ ๊ณต๋ถ€ํ•œ์ง€ ์–ผ๋งˆ ์•ˆ๋œ์ฑ„๋กœ ํˆฌ์ž…๋˜์–ด์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ผ๋‹จ ์ข‹๋‹ค๋‹ˆ๊นŒ ์‚ฌ์šฉํ–ˆ์—ˆ๊ณ , ํ•ญ์ƒ ์‹œ๊ฐ„์— ์ซ“๊ฒจ ์ œ๋Œ€๋กœ ๊ณต๋ถ€ํ•ด ๋ณผ ์‹œ๊ฐ„์ด ์—†์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  DND ํ”„๋กœ์ ํŠธ๋„ ์ฃผ์–ด์ง€๋Š” ๊ณต์‹์ ์ธ ๊ฐœ๋ฐœ๊ธฐ๊ฐ„์ด 8์ฃผ๋ฐ–์— ์•ˆ๋˜๊ธฐ์— ์ผ๋‹จ ๋˜๋Š”๋Œ€๋กœ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜จ ์ฒด๊ณ„์—†๋Š” ์ฝ”๋“œ์ด๋‹ค.

// types/IUser.ts
// ํŽธ์˜์  ๊ทผ๋ฌด๊ด€๋ฆฌ ์„œ๋น„์Šค ํŠน์„ฑ์ด ๋ฐ˜์˜๋œ ์œ ์ € ํƒ€์ž…์„ ์–ธ
export type RoleType = 'WORKER' | 'MANAGER';
export interface IUser {
	userName: string;
	userProfileCode: number;
    workPlace: string; 
	workLocation: string;
	workTime: string; 
	role: RoleType;
	phoneNumber: string | null; //์ „ํ™”๋ฒˆํ˜ธ(๋ฏผ๊ฐํ•œ ๊ฐœ์ธ์ •๋ณด)๋Š” ์ž…๋ ฅํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. 
	wage: string;
	email: string;
}
// ์œ ์ € ํšŒ์›๊ฐ€์ž…์— ์‚ฌ์šฉ๋œ Zustand Store ํŒŒ์ผ

// ์œ ์ € ๋“ฑ๋ก ํผ ํƒ€์ž… ์„ ์–ธ
interface IUserForm {
	role: RoleType | null;
	workPlace: string | null;
	workLocation: string | null;
	workTime: string;
	phoneNumber: string | null;
	wage: string | null;
}
// ์œ ์ € post api ์—ฐ๋™ 
export interface MutateUserBody {
	role: RoleType;
	workPlace: string;
	workLocation: string;
	workTime: string; // "์›”(17:00~21:00),ํ™”(17:00~21:00)"
	phoneNumber: string | null; // "010-0000-0000"
	wage: number;
}


export const postUser = async (body: MutateUserBodyType) => {
	const res = await client.post(`/api/user/signup`, { ...body });
	return res;
};

๐Ÿง์™œ ์ž๊พธ ๊ฐ™์€ ํƒ€์ž…์„ ๋˜! ์ •์˜๋ฅผ ํ•˜์ง€? ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ!

ํ•œ ๋ฒˆ ์ •์˜๋œ ์œ ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ, ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์˜์—ญ์—์„œ ํƒ€์ž…์ด ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ์•ˆ์ •์ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด๊ฐ€ IUser์—์„œ wage๋ฅผ string์œผ๋กœ ํƒ€์ž…์„ ์„ ์–ธํ•ด ๋‘์—ˆ์œผ๋ฉด ์œ ์ €์˜ wage๋Š” ํ•ญ์ƒ stringํƒ€์ž…์ด์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์œ„์ฒ˜๋Ÿผ ์ค‘๊ตฌ๋‚œ๋ฐฉ์œผ๋กœ ์—ฌ๋ŸฌํŒŒ์ผ์—์„œ ์œ ์ €์˜ ํƒ€์ž…์„ ์žฌ์ •์˜ํ•˜๋‹ค ๋ณด๋ฉด wage๋ฅผ number๋กœ ์„ ์–ธํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค. ๋™์ผํ•œ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ๋Š” ์ค‘๋ณต ์„ ์–ธ์„ ํ•˜์ง€ ์•Š๊ณ , ๊ธฐ์กด์— ์ •์˜ํ•œ ๊ฒƒ์„ ์žฌํ™œ์šฉํ•ด์•ผํ•œ๋‹ค.์ด๋ฅผ ์œ„ํ•ด Pick๊ณผ Partial์ด๋ผ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค. (+Omit?) ๊ทธ๋ฆฌ๊ณ  mapped type์„ ํ™œ์šฉํ•ด ๊ธฐ์กด ์ •์˜๋œ ํƒ€์ž…์„ ์žฌํ™œ์šฉํ–ˆ๋‹ค.


Partial

  • Partial๋กœ ํŠน์ • ํƒ€์ž…์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ๋งŒ์กฑํ•˜๋Š” ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๊ธฐ์กด์— ์œ ์ € ๋“ฑ๋ก์„ ์œ„ํ•ด ๋งŒ๋“  Zustand Store ํŒŒ์ผ์—์„œ ์œ ์ € ๋“ฑ๋ก Form type์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐœ์„  ๋  ์ˆ˜ ์žˆ๋‹ค.

// ์œ ์ € ํšŒ์›๊ฐ€์ž…์— ์‚ฌ์šฉ๋œ Zustand Store ํŒŒ์ผ

//BEFORE
interface IUserForm {
	role: RoleType | null;
	workPlace: string | null;
	workLocation: string | null;
	workTime: string;
	phoneNumber: string | null;
	wage: string | null;
}


//AFTER
type UserFormType = Partial<IUser> & { workTimeObj?: WeekWorkTimeType }; // ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ํ•„๋“œ๋Š” undefiend ์ƒํƒœ 

Pick<T,K>

  • T์—์„œ ํ”„๋กœํผํ‹ฐ K์˜ ์ง‘ํ•ฉ์„ ์„ ํƒํ•ด ํƒ€์ž…์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ์กด์— ์œ ์ € ๋“ฑ๋ก์„ ์œ„ํ•ด ์ •์˜ํ•œ ํƒ€์ž…์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐœ์„ ๋  ์ˆ˜ ์žˆ๋‹ค.

// BEFORE
export interface MutateUserBody {
	role: RoleType;
	workPlace: string;
	workLocation: string;
	workTime: string; // "์›”(17:00~21:00),ํ™”(17:00~21:00)"
	phoneNumber: string | null; // "010-0000-0000"
	wage: number;
}

// AFTER

export type MutateUserBodyType = Pick<
	IUser,
	'role' | 'workPlace' | 'workLocation' | 'workTime' | 'phoneNumber' | 'wage'
>; 

Omit<T,K>

  • T์—์„œ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ K๋ฅผ ์ œ๊ฑฐํ•œ ํƒ€์ž…์„ ๊ตฌ์„ฑํ•œ๋‹ค.
    ์‚ฌ์‹ค ์œ„์—์„œ ์ž‘์„ฑํ•œ MutateUserBodyType์€ Omit์œผ๋กœ userName,userProfileCode์„ ์ œ๊ฑฐํ•œ ํƒ€์ž…์ด๋ผ๊ณ  ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•„์š”ํ•œ ์œ ์ € ํ•„๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ฝ”๋“œ์ƒ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์ด๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๊ธฐ์— Pick์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•˜์˜€๋‹ค.

Mapped Type

๋งˆ์ง€๋ง‰์œผ๋กœ ์œ ์ €์˜ ์ •๋ณด๋ฅผ prop์œผ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ interface๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ์กด ์ •์˜ํ•œ ์œ ์ €์˜ ํƒ€์ž…์„ mappingํ•ด ์ฃผ์—ˆ๋‹ค.

interface Props {
	userProfileCode: IUser['userProfileCode'];
	userName: IUser['userName'];
	workTime: IUser['workTime'];
	email: IUser['email'];
}

function UserProfile({ userProfileCode, userName, workTime, email }: Props) {
 --- ์ดํ•˜ ์ƒ๋žต ---

profile
์ผ๋‹จ ํ•˜๋Š” ์ค‘

0๊ฐœ์˜ ๋Œ“๊ธ€