프로젝트를 진행하면서 한 번 본 적이 있지만 귀찮아서 제대로 확인하지 않았던 부분을 조사했습니다.
초보적인 내용이 많아 조금 부끄럽지만, 다음에 볼 때 잊지 않기 위한 메모로 남겨둡니다!
(아래 예시가 궁금하신 분은 읽어보셔도 좋습니다!)
1 . K extends keyof T
K extends keyof T
부분을 자주 보았습니다.
keyof
는 객체 타입의 키를 유니온 타입 형태로 변환해주는 기능이고, extends
는 해당 타입을 상속하는 기능입니다.
따라서, 1-1의 예시에서 사용되는 경우를 해석하면, K extends keyof T
는 T라는 객체 타입의 키 값을 유니온 타입으로 추출해 이를 K 타입으로 사용하는 의미가 됩니다.
결과적으로, K는 "a" | "b" | "c" | "d"
와 같은 형태가 됩니다.
아래 1-2와 1-2의 예시를 통해 새롭게 알게 된 점은 다음과 같습니다.
1-1의 예시에서 놓쳤던 점은 제네릭은 선언 부분에서 사용하고, 호출 시에는 생략이 가능하다는 점이었습니다.
또한, 1-2에서 몰랐던 점으로, 객체 타입의 값을 타입으로 선언할 때는
객체타입[키타입]
형식으로 표현된다는 것을 알게 되었습니다.
1-1
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a"); // 성공
getProperty(x, "m"); // 에러: 'm'은 'a' | 'b' | 'c' | 'd'에 해당하지 않습니다.
1-2
// 객체의 특정 프로퍼티를 업데이트하는 제네릭 함수
function updateProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): T {
return { ...obj, [key]: value };
}
// User 타입 정의
type User = {
id: number;
name: string;
age: number;
};
// User 객체 생성
const user: User = {
id: 1,
name: "Alice",
age: 25,
};
// User 객체의 name 프로퍼티 업데이트
const updatedUser = updateProperty(user, "name", "Bob");
console.log(updatedUser); // { id: 1, name: "Bob", age: 25 }
// User 객체의 age 프로퍼티 업데이트
const olderUser = updateProperty(user, "age", 30);
console.log(olderUser); // { id: 1, name: "Alice", age: 30 }
2. Generic을 사용하는 예제
제네릭이 실제로 어떻게 사용되는지 조사한 결과, 아래와 같은 경우가 있다는 것을 알게 되었습니다.
null을 허용하는 타입을 선언하는 경우, 아래와 같은 방법으로 사용할 수 있습니다.
또한 2-1의 예시를 조사하며 타입에도 제네릭이 사용될 수 있다는 것을 알게 되었습니다.
2-1
type Nullable<T> = T | null;
// 사용자 정보의 타입 정의
type User = {
id: number;
name: string;
};
// User 타입에 Nullable 적용
const user1: Nullable<User> = { id: 1, name: "Alice" };
const user2: Nullable<User> = null; // null 허용
// 숫자 타입에 Nullable 적용
const age: Nullable<number> = 30;
const unknownAge: Nullable<number> = null; // null 허용
3.keyof typeof
keyof typeof
객체 이름은 자주 보이지만, 왜 사용되는지 몰랐던 기초적인 부분입니다.
객체 자체에서 바로 키를 유니온 타입으로 추출할 수 없습니다.
따라서, 먼저 typeof
로 객체를 타입으로 변환한 후, keyof
를 사용해 키를 타입으로 추출하는 방식이라는 것을 이해했습니다.
// 객체 정의
const userRoles = {
admin: "관리자",
user: "사용자",
guest: "게스트",
};
// `keyof typeof`를 사용하여 키 타입 추출
type UserRole = keyof typeof userRoles;
// 함수 예제
function getRole(role: UserRole) {
console.log(`역할: ${role}, 설명: ${userRoles[role]}`);
}
// 함수 호출
getRole("admin"); // 출력: 역할: admin, 설명: 관리자
getRole("user"); // 출력: 역할: user, 설명: 사용자
// getRole("superuser"); // 에러: 'superuser'는 UserRole 타입에 존재하지 않습니다.