๐งโโ๏ธ 05. ๊ณ ๊ธ ํ์ ์กฐ์: ์์๋ค ์ปค๋ฎค๋ํฐ ๊ถํ ๋งคํ ์ค๊ณ
๐ ๊ฐ์
keyof, typeof, Mapped Types๋ฅผ ํ์ฉํด ์ค๋ณต ์๋ ์ ์ธ์ ์ธ ํ์ ์์คํ ์ค๊ณํ๊ธฐ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 15๋ถ(์ ์ฒด) / ํต์ฌ ํํธ๋ง: 8๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
[typeof์ keyof์ ์ง์ง ์๋ฏธ] โ [๋งต๋ ํ์
(Mapped Types)์ผ๋ก ๋
ธ๊ฐ๋ค ํ์ถํ๊ธฐ] โ [์กฐ๊ฑด๋ถ ํ์
(Conditional Types) ๋ง๋ณด๊ธฐ]
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ(Value) ๊ณต๊ฐ์์ ํ๋ํ๋ ๋ณ์๋ฅผ ํ์ (Type) ๊ณต๊ฐ์ผ๋ก ๊น๋ํ๊ฒ ๋์ด์ฌ๋ฆด ์ ์๋ค.
- ์์ญ ๊ฐ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ๊ฐ์ฒด ํ์ ์ ๋จ 3์ค์ ์ฝ๋๋ก ์ผ๊ด ๋ณํ(Mapped Type)ํ ์ ์๋ค.
- 5๋
์ฐจ ์์ค์ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์
(
Partial,Pick,Omit์ ๋ด๋ถ ์๋ฆฌ)์ ์ดํดํ๊ณ ์ง์ ๊ตฌํํ ์ ์๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ๐ฃ ์์ฒ ( ํ์
์ค๋ณต์ ์ค์ฌ๊ฐ๋ ์ค ): "๋ฆฌ๋ ๋! ๋ฐฑ์๋์์ ์ฌ์ฉ์ ํ๋กํ ์ ๋ณด(
UserProfile)๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ, ๊ฐ์ ํ ๋ ์ฐ๋ '์์ ๊ฐ๋ฅํ ํผ ๋ฐ์ดํฐ' ํ์ ์ ์๋ก ๋ง๋ค์ด์ผ ํด์. ๊ธฐ์กดUserProfile์ ๋ณต์ฌํด์id๋ฅผ ๋นผ๊ณ ์ ๋ถ optional๋ก ๋ฐ๊พธ๊ณ ์๋๋ฐ, ์ด๋ฌ๋ฉด ์๋ณธ ํ์ ์ด ๋ฐ๋ ๋๋ง๋ค ๋์น ๊ฒ ๊ฐ์ต๋๋ค." - ๐ฆ ์ํธ ( ๋ฆฌ๋ ): "์ข์ ๊ฐ์ง์
๋๋ค. ์ ๋ค๋ฆญ๊น์ง ๋ฐฐ์ ๋ค๋ฉด ์ด์ ๊ธฐ์กด ํ์
์ ์ฌ๋ฃ๋ก ์ ํ์
์ ๋ง๋๋ ๋จ๊ณ๋ก ๋์ด๊ฐ ์ฐจ๋ก์์.
typeof,keyof, ๋งต๋ ํ์ ์ ์ฐ๋ฉด ์ค๋ณต ์ ์ธ ๋์ ์๋ณธ ํ์ ๊ณผ ํจ๊ป ์์ง์ด๋ ํ์ ํ์ ์ ๋ง๋ค ์ ์์ต๋๋ค."
๐ค ์ ์์์ผ ํ๋๊ฐ: '๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ'์ ๋์๋ ๋ช
์ด๋ณด ์์ ์ ํ์ ์คํฌ๋ฆฝํธ๋ "๋ด๊ฐ ๋ง๋ ๋ณ์์ ์ธํฐํ์ด์ค ํ๋ ๋ฌ์์ฃผ๊ธฐ" ์ ๋๋ฉด ์ถฉ๋ถํฉ๋๋ค. ํ์ง๋ง ํ๋ก์ ํธ๊ฐ ์ปค์ง๋ฉด "๊ธฐ์กด์ ์๋ A ํ์ ์ ์์ฃผ ์ด์ง๋ง ๋ฐ๊ฟ์ B ํ์ ์ ๋ง๋ค๊ณ ์ถ๋ค" ๋ ์๋ง์ด ๋์ด์ค๋ฆ ๋๋ค.
์์๋ค ์ปค๋ฎค๋ํฐ์ ๊ถํ ๊ฐ์ฒด๊ฐ ์๋ค๊ณ ์นฉ์๋ค.
// ๐ฃ ์์ฒ ์ด์ ๋ณต๋ถ ๋
ธ๊ฐ๋ค
interface UserProfile {
id: number;
name: string;
email: string;
age: number;
}
// ํ์ ์ ๋ณด ์์ ํผ์ ์ํด ๋ชจ๋ ํ๋๋ฅผ ์ ํ์ (Optional)์ผ๋ก ๋ง๋ค๊ณ ์ถ์
interface UserProfileUpdateForm {
id?: number;
name?: string;
email?: string;
age?: number;
}๋์ค์ ์์(๋ฐฑ์๋)๊ฐ UserProfile์ phoneNumber: string์ ์ถ๊ฐํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
๋ค, ์์ฒ ์ด๋ ๋ ์ผ๊ทผํ๋ฉฐ UserProfileUpdateForm์ ์ฐพ์ phoneNumber?: string์ ์์ ์ ์ด ๋ฃ์ด์ผ ํฉ๋๋ค. ์ด๋ฐ ์ง์ ๋ง๊ธฐ ์ํด 5๋
์ฐจ ๊ฐ๋ฐ์๋ค์ ํ์
์กฐ์(Type Manipulation) ์ ๋ฌด๊ธฐ๋ก ์ผ์ต๋๋ค.
๐ช 1. ๊ฐ(Value)๊ณผ ํ์
(Type)์ ์ธ๊ณ๋ฅผ ๊ฐ๋ก์ง๋ฅด๊ธฐ: typeof & keyof
์ด ๊ณ ๊ธ ํ์ ์กฐ์์ ์ฒซ ๋จ์ถ๋ JS ์ธ์์ ๋ฐํ์ ๋ฐ์ดํฐ์ TS ์ธ์์ ์ปดํ์ผ ํ์ ์ ์ ํํ ์ค๊ฐ๋ ์ฐ์ฐ์๋ค์ ๋๋ค.
typeof: JS ๋ณ์์์ ํ์
๋ฝ์์ค๊ธฐ
// JS์ ๊ฐ(Value) ์ธ์
const ROLE_NAMES = {
ADMIN: "์ต๊ณ ๊ด๋ฆฌ์",
MANAGER: "๊ฒ์ํ ๊ด๋ฆฌ์",
USER: "์ผ๋ฐ ์ฌ์ฉ์"
};
// ๐ฆ ์ํธ: "์ ๊ฐ์ฒด์ ๋ชจ์ํ๋ฅผ ๊ทธ๋๋ก ํ์
์ธ์์ผ๋ก ๋ฉ์นํด ๋ด
์๋ค!"
type RoleMap = typeof ROLE_NAMES;
/*
๊ฒฐ๊ณผ:
type RoleMap = {
ADMIN: string;
MANAGER: string;
USER: string;
}
*/์ด ๊ธฐ๋ฒ์ Redux์ ์ด๊ธฐ ์ํ(initialState)๋ ๊ณตํต ์์ ๊ฐ์ฒด์์๋ถํฐ ํ์ดํ์ ์์ํ ๋ ๊ต์ฅํ ์ ์ฉํฉ๋๋ค. JS ์ฝ๋๋ฅผ ๋จผ์ ์ง๊ณ , ๊ทธ ์์ TS๋ฅผ ๋ถ๋๋ฝ๊ฒ ์น๋ ๋ฐฉ์์ด์ฃ .
keyof: ๊ฐ์ฒด์ 'ํค'๋ค๋ง ๋ฝ์์ ์ ๋์ธ์ผ๋ก ๋ง๋ค๊ธฐ
๊ฐ์ฒด์ ํ์
์ ํต์งธ๋ก ๋ฝ๋ ๊ฒ typeof๋ผ๋ฉด, ๊ทธ ๊ฐ์ฒด์ ํค(Key)๊ฐ๋ค๋ง ๋นผ๊ณกํ ๋ฝ์๋ด๊ณ ์ถ์ ๋๋ keyof๋ฅผ ์๋๋ค.
type UserKeys = keyof UserProfile;
// ๊ฒฐ๊ณผ: "id" | "name" | "email" | "age"
// ํ์ฉ: ํ๋ผ๋ฏธํฐ๋ก ๋ฌด์กฐ๊ฑด UserProfile์ ํค๊ฐ ์ค ํ๋๋ง ๋ค์ด์ค๋๋ก ๊ฐ์ !
function getProperty(user: UserProfile, key: keyof UserProfile) {
return user[key];
}
getProperty(myUser, "name"); // โ
ํต๊ณผ
// getProperty(myUser, "password"); // โ ์๋ฌ: password๋ UserProfile์ ํค๊ฐ ์๋๋๋ค!๐จ 2. ๋งต๋ ํ์ (Mapped Types): ํ์ ๋ค์ ๋๋ ์์ฐ ๊ณต์ฅ
์, ์ด์ ์์ฒ ์ด์ ์ผ๊ทผ ์ํ์ด์๋ ๋ณต๋ถ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ด
์๋ค.
๋ฐฐ์ด์ ๋ ๋ .map()์ ์ฐ๋ฏ, ๊ฐ์ฒด์ ๋ชจ๋ ํค๋ฅผ ์ํํ๋ฉฐ ์์ฑ์ ์ผ๊ด ๋ณ๊ฒฝํ๋ ๋๊ตฌ๊ฐ ๋ฐ๋ก ๋งต๋ ํ์
์
๋๋ค.
// ๐ฆ ์ํธ: "T๋ผ๋ ๊ฐ์ฒด๊ฐ ๋ค์ด์ค๋ฉด, ๊ทธ ๊ฐ์ฒด์ ๋ชจ๋ ํค(K)๋ฅผ ์ํํ๋ฉด์ ์ต์
๋(?)์ ๋ถ์ฌ๋ฒ๋ ค!"
type MakeOptional<T> = {
[K in keyof T]?: T[K]; // ๋ชจ๋ ํค๋ฅผ ์ํํ๋ฉฐ ์ ํ ์์ฑ์ผ๋ก ๋ฐ๊พผ๋ค.
};
// ์์ฒ ์ด์ ๊ตฌ์ธ์ฃผ
type UserProfileUpdateForm = MakeOptional<UserProfile>;
/*
๊ฒฐ๊ณผ:
type UserProfileUpdateForm = {
id?: number | undefined;
name?: string | undefined;
email?: string | undefined;
age?: number | undefined;
}
*/์ด ํจํด์ ๋๋ฌด๋๋ ๋ง์ด ์ฐ์ฌ์, ํ์
์คํฌ๋ฆฝํธ๊ฐ ์์ Partial<T> ๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ด์ฅ ์ ํธ๋ฆฌํฐ ํ์
์ ๋ง๋ค์ด ๋์์ต๋๋ค. Readonly<T>, Pick<T, K>, Omit<T, K> ๋ฑ ์ฌ๋ฌ๋ถ์ด ์ฐ๋ ์ ์ฉํ ๋ฌธ๋ฒ๋ค์ด ์ ๋ถ ์ด ๋งต๋ ํ์
๊ณผ keyof๋ก ๋ง๋ค์ด์ ธ ์์ต๋๋ค.
โ๏ธ 3. ์กฐ๊ฑด๋ถ ํ์ (Conditional Types): ํ์ ์๋ If๋ฌธ์ด ์๋ค
๋๋ก๋ ์ผํญ ์ฐ์ฐ์(A ? B : C)์ฒ๋ผ "์ด ํ์
์ด ์ ๊ธฐ๋ฅผ ๋ง์กฑํ๋ฉด A๋ฅผ ๋ฐํํ๊ณ , ์๋๋ฉด B๋ฅผ ๋ฐํํด!" ๋ผ๋ ๋ก์ง์ด ํ์ํ ๋๊ฐ ์์ต๋๋ค. (์ฃผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์์๋ค์ด ๋ง์ด ์๋๋ค.)
// T๊ฐ ๋ฌธ์์ด์ด๋ฉด ์ซ์ ํ์
์ ๋ฐํํ๊ณ , ์๋๋ฉด ๊ทธ๋ฅ ๋ฌธ์์ด์ ๋ฐํํ๋ผ!
type NumberIfString<T> = T extends string ? number : string;
type Test1 = NumberIfString<"์๋
">; // Test1์ number ํ์
์ด ๋จ
type Test2 = NumberIfString<boolean>; // Test2๋ string ํ์
์ด ๋จ์ค๋ฌด์์๋ ์ด๋ฅผ ํ์ฉํด ํน์ ํ์
๋ง ํํฐ๋งํ๊ฑฐ๋ ์ถ์ถํ๋ ๋ฐ ์๋๋ค. ์๋ฅผ ๋ค์ด ์์์ ๋ง๋ UserProfile์์ ๊ฐ์ด string์ธ ํ๋กํผํฐ ํค๊ฐ๋ง ๋ฝ์๋ด๊ณ ์ถ์ ๋ ์กฐ๊ฑด๋ถ ํ์
์ ์กฐํฉํ ์ ์์ต๋๋ค. ๋น์ฅ ๋ชจ๋ ํจํด์ ์ธ์ธ ํ์๋ ์์ง๋ง, ๊ถํ/ํผ/์๋ต ํ์
์ ์ค๊ณํ ๋ ์ด๋ฐ ์กฐํฉ์ด ๋ฐ๋ณตํด์ ๋ฑ์ฅํฉ๋๋ค.
๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. ์๋ฐ์คํฌ๋ฆฝํธ์ ์์ ํ์ผ(const COLORS = { RED: '#f00', BLUE: '#00f' })์ด ์์ ๋, ์ด ๊ฐ์ฒด์ ํํ๋ฅผ ๋ฐํ์ผ๋ก type ColorsType์ ์๋์ผ๋ก ๋ง๋ค์ด๋ด๊ณ ์ถ์ต๋๋ค. ์ด๋ค ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋์?
โ
์ ๋ต: typeof ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. (์: type ColorsType = typeof COLORS;)
๐ก ์์ธ ํด์ค:
- JS์ ๋ฐํ์ ๊ฐ์ผ๋ก๋ถํฐ TS์ ํ์
๊ตฌ์กฐ๋ฅผ ์ถ์ถ(์ถ๋ก )ํ ๋ ์ฒซ ๋ฒ์งธ ๊ด๋ฌธ์ด ๋ฐ๋ก
typeofํค์๋์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋์ค์ ์์ ๊ฐ์ฒด์GREEN: '#0f0'์ด ์ถ๊ฐ๋๋๋ผ๋ColorsType์ ์๋์ผ๋กGREEN์ด ํฌํจ๋๋ฏ๋ก ์ ์ง๋ณด์๊ฐ ๊ทน๋๋ก ํธํด์ง๋๋ค.
Q2. keyof ์ฐ์ฐ์๋ฅผ ๋ฐฐ์ด(Array) ํ์
์ ์ ์ฉํ๋ฉด ์ด๋ค ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋ ๊น์? (์: type ArrayKeys = keyof string[];)
โ
์ ๋ต: ๋ฐฐ์ด์ ์ธ๋ฑ์ค์ธ number ํํ์ ๋ฐฐ์ด ํ๋กํ ํ์
์ ์๋ ๋ฉ์๋ ์ด๋ฆ๋ค("length" | "push" | "pop" | "map" ๋ฑ...)์ด ํต์งธ๋ก ์ ๋์ธ์ผ๋ก ๋ฐํ๋ฉ๋๋ค.
๐ก ์์ธ ํด์ค:
keyof๋ ๊ฐ์ฒด์ "ํค"๋ฅผ ์ถ์ถํฉ๋๋ค. ๋ฐฐ์ด ์ญ์ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ธ๋ฑ์ค(0, 1, 2...)๋ฅผ ํค๋ก ๊ฐ์ง๊ณ ๋ฆฌ์คํธ ๊ด๋ จ ๋ฉ์๋๋ฅผ ์์ฑ์ผ๋ก ๊ฐ๋ ๊ฑฐ๋ํ ๊ฐ์ฒด์ ๋๋ค.- ๊ทธ๋์ ๋ฐฐ์ด์ ๋๊ณ
keyof๋ฅผ ์ฐ๋ฉด ์ฌ์ค์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊น๋ํ ๋ฐ์ดํฐ๋ณด๋ค ๋ด์ฅ ํจ์ ์ด๋ฆ์ด ์์์ ธ ๋์ค๊ฒ ๋๋ฏ๋ก, ๋ฐฐ์ด ๋ด๋ถ ์์๋ฅผ ๋ค๋ฃฐ ๋๋T[number]ํํ์ ์ธ๋ฑ์ค๋ ์ก์ธ์ค(Indexed Access)๋ฅผ ๋ ์์ฃผ ์ฌ์ฉํฉ๋๋ค.
Q3. [์์ฒ ์ด์ ํ
์คํธ ํ์: ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํธ๋ ์ด๋์คํ] ์์๋ค ์ปค๋ฎค๋ํฐ์ API ๊ณตํต ์ ํธ ํด๋๋ฅผ ๋ณด๋ ์์ฒ ์ด๊ฐ ๊น์ง ๋๋๋๋ค. "๋ฆฌ๋ ๋! TS ๋ด์ฅ ์ ํธ๋ฆฌํฐ์ธ Partial<T>, Required<T>, Readonly<T> ๊ฐ์ ๊ฒ ์ ๋ถ ๋ด๋ถ ์ฝ๋๋ฅผ ๊น๋ณด๋ [P in keyof T] ๋ผ๋ ๋๊ฐ์ ๋ฌธ๋ฒ์ผ๋ก ์์ํ๋ค์? ์ด๊ฑด ๋ญ๊ฐ์?" ๋ผ๊ณ ๋ฌป๋ ์์ฒ ์๊ฒ ์ํธ๋ ์ด๋ค ๊ฐ๋
์ ์ค๋ช
ํด ์ค๊น์?
โ ์ ๋ต: "์์ฒ ๋, ๊ทธ๊ฒ ๋ฐ๋ก ๋งต๋ ํ์ (Mapped Type)์ ํต์ฌ ๊ณจ๊ฒฉ์ ๋๋ค. ๊ฐ์ฒด์ ํค๋ฅผ ์ํํ๋ฉฐ ์์ฑ์ ์ผ๊ด ์กฐ์ํ๋ ๋ฌธ๋ฒ์ด์ฃ ."
๐ก ์์ธ ํด์ค:
- ์๋ฆฌ ์ค๋ช
:
[P in keyof T]๋ ๋ง์น JS์for...in๋ฐ๋ณต๋ฌธ์ฒ๋ผ ์๋ํฉ๋๋ค.T๋ผ๋ ๊ฐ์ฒด์ ๋ชจ๋ ํค(keyof T)๋ฅผ ํ๋์ฉP๋ผ๋ ๋ณ์์ ๋ด์๊ฐ๋ฉด์, ๊ทธ ๊ฒฐ๊ณผ๋ฌผ ํ์ ์ ์ต์ ๋(?:), ์ฝ๊ธฐ ์ ์ฉ(readonly), ๋๋ ์๋ ํ์ (T[P]) ๋ฑ์ผ๋ก ํต์งธ๋ก ๋งตํ(Mapping)ํ๋ ๊ฒ ๋ฐ๋ก ์ ์ ์ฐ๋ช ํ ์ ํธ๋ฆฌํฐ๋ค์ ๋ฏผ๋ฏ์ ๋๋ค. - ๋ด์ฅ ์ ํธ๋ฆฌํฐ๋ฅผ ์ฐ๋ ๊ฒ์์ ๋๋์ง ์๊ณ , ์ฐ๋ฆฌ ์๋น์ค ๊ท์น์ ๋ง์ถ ํ์ ํ์ ์ ๋ง๋ค ๋๋ ๊ฐ์ ์๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ชจ๋ ํผ ํ๋๋ฅผ nullableํ๊ฒ ๋ง๋ค๊ฑฐ๋, ์๋ฒ ์๋ต์์ ์ฝ๊ธฐ ์ ์ฉ ํ๋๋ฅผ ๋ถ๋ฆฌํ ๋ ์ ์ฉํฉ๋๋ค.
- ํต์ฌ์ ๊ฐ์ฒด ํ์ ์ ํค๋ฅผ ํ ๋ฒ์ฉ ์ํํ๋ฉด์ ๊ฐ ์์ฑ์ ์ ํ์ฑ, ์ฝ๊ธฐ ์ ์ฉ ์ฌ๋ถ, ๊ฐ ํ์ ์ ์ผ๊ด๋๊ฒ ๋ฐ๊พธ๋ ๊ฒ์ ๋๋ค.
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
์ค๋์ ํ์
์ ๋ณต์ฌํด์ ์๋ก ๋ง๋๋ ์ต๊ด์ด ์ผ๋ง๋ ์ํํ์ง ์์๋ค. UserProfile์ด ๋ฐ๋์๋๋ฐ UserProfileUpdateForm์ด ๊ทธ๋๋ก ๋จ์ ์์ผ๋ฉด, ํ์
์คํฌ๋ฆฝํธ๊ฐ ์๋๋ผ ๋ด๊ฐ ์ค๋ณต์ ๋ง๋ ํ์ด๋ค.
typeof๋ ๊ฐ์์ ํ์
์ ๋์ด์ค๊ณ , keyof๋ ํค ๋ชฉ๋ก์ ์ ๋์ธ์ผ๋ก ๋ง๋ค๊ณ , ๋งต๋ ํ์
์ ๊ทธ ํค๋ค์ ๋ฐ๋ผ ์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๋ค. Partial, Pick, Omit์ด ๊ฐ์๊ธฐ ์ธ์์ผ ํ ์ด๋ฆ์ด ์๋๋ผ ์ฝ์ ์ ์๋ ์ฝ๋์ฒ๋ผ ๋ณด์ด๊ธฐ ์์ํ๋ค.
๐ก "ํ์ ํ์ ์ ์๋ณธ ํ์ ๊ณผ ํจ๊ป ์์ง์ฌ์ผ ํ๋ค. ๋ณต์ฌ๋ณธ์ ๋๋ฆฌ๋ ๋์
keyof, ๋งต๋ ํ์ , ์ ํธ๋ฆฌํฐ ํ์ ์ผ๋ก ๊ด๊ณ๋ฅผ ์ ์ธํ์."
๋ด์ผ์ ๊ถํ ์์์ ํ๋กํ ํผ ํ์ ๋ถํฐ ํ์ธํด๋ณด๋ ค๊ณ ํ๋ค. ์๋ณธ ๊ฐ์ฒด๋ ์ธํฐํ์ด์ค์์ ๋ฐ๋ก ํ์ํ ์ ์๋ ํ์ ์ ์์ผ๋ก ๋ค์ ์ฐ์ง ์๊ณ , ๋ณ๊ฒฝ์ด ํ ๊ณณ์์ ํ๋ฅด๋๋ก ๋ง๋๋ ๊ฒ ๋ชฉํ๋ค.