유틸리티 타입
Partial · Pick · Omit · Record 로 있는 타입을 고쳐 씁니다.
있는 타입을 고쳐 씁니다
User 를 적어 두었는데, 어떤 자리에서는 일부만
필요하고 어떤 자리에서는 전부 없어도 되는 형태가 필요합니다. 그때마다
비슷한 타입을 다시 적으면 하나가 바뀔 때 여럿을 고쳐야 합니다.
TypeScript 가 미리 만들어 둔 것들이 있습니다. 제네릭(3.3)으로 되어 있어 꺾쇠 안에 고칠 타입을 넣습니다.
| 이름 | 하는 일 |
|---|---|
Partial<T> | 모든 속성을 없어도 되게 만듭니다 |
Required<T> | 반대로, 모두 있어야 하게 만듭니다 |
Readonly<T> | 모두 바꿀 수 없게 만듭니다 |
Pick<T, K> | 고른 속성만 남깁니다 |
Omit<T, K> | 고른 속성만 뺍니다 |
Record<K, V> | 정해진 열쇠마다 값을 갖는 객체를 만듭니다 |
일부만 바꾸기 — Partial
interface User { name: string; age: number; email: string; } function update(user: User, changes: Partial<User>): User { return { ...user, ...changes }; } const before: User = { name: "홍길동", age: 27, email: "a@b.c" }; const after = update(before, { age: 28 }); console.log(after.name, after.age, after.email);
changes 에는 바꿀 것만 넘깁니다.
Partial<User> 가
{ name?: string; age?: number; email?: string } 와
같기 때문입니다.
User 에 속성을 하나 더하면
Partial<User> 도 저절로 따라옵니다.
이것이 다시 적지 않는 값입니다.
고르고 빼기 — Pick 과 Omit
interface User { name: string; age: number; password: string; } type PublicUser = Pick<User, "name" | "age">; type Safe = Omit<User, "password">; const a: PublicUser = { name: "홍길동", age: 27 }; const b: Safe = { name: "김철수", age: 31 }; console.log(a.name, b.age);
둘은 같은 결과를 다르게 적은 것입니다. 어느 쪽이 나은지는 무엇이 바뀔지에
달려 있습니다. 속성이 늘어날 때 새 속성을 내보내고 싶으면
Omit, 내보내지 않으려면
Pick 이 안전합니다.
열쇠마다 값 — Record
type Level = "low" | "mid" | "high"; const label: Record<Level, string> = { low: "낮음", mid: "보통", high: "높음" }; console.log(label.low, label.high);
빠뜨리면 막습니다. 값이 늘었는데 표를 고치지 않는 일을 잡아 줍니다.
type Level = "low" | "mid" | "high"; const label: Record<Level, string> = { low: "낮음", mid: "보통" };
처음에 자주 걸리는 것
Pick<User, name> 이 아니라
Pick<User, "name"> 입니다. 이름 자체가
리터럴 타입(1.4)이기 때문입니다.
모든 것을 없어도 되게 만들면 확인할 것이 늘어납니다. 값이 없을 수 있다는 뜻이므로 쓰는 쪽에서 매번 다뤄야 합니다. 실제로 일부만 넘기는 자리에만 사용합니다.
Omit<User, "passwrod"> 처럼 오타를 적어도
오류가 아닙니다. 뺄 것이 없을 뿐입니다. Pick 은
없는 이름을 적으면 막습니다.
직접 해보기
id · name ·
email 을 담는 타입에서, 새로 만들 때 입력하는
폼용 타입(아이디 제외)을 만드세요.
interface User {
id: number;
name: string;
email: string;
}
type UserForm = Omit<User, "id">;
const form: UserForm = { name: "홍길동", email: "a@b.c" };
console.log(form.name, form.email);
"pending" | "done" | "failed" 마다 안내 문구를
갖는 표를 Record 로 만드세요.
type Status = "pending" | "done" | "failed";
const message: Record<Status, string> = {
pending: "처리하고 있습니다",
done: "끝났습니다",
failed: "실패했습니다"
};
console.log(message.pending);
console.log(message.failed);이 단원의 정리
- 있는 타입을 고쳐 새 타입을 만드는 것들이 미리 준비되어 있습니다.
Partial은 모두 없어도 되게,Required는 모두 있어야 하게 만듭니다.Pick은 고른 것만 남기고Omit은 고른 것만 뺍니다.Record는 정해진 열쇠마다 값을 갖게 하고, 빠뜨리면 막습니다.- 원본이 바뀌면 이것들도 저절로 따라옵니다.