nest.js
TypeScript Generics, Typescript-utility (2024.05.30)
goblin-
2024. 5. 30. 14:55
TypeScript Generics
Generics란?
- Generics는 함수, 클래스, 인터페이스에서 사용할 수 있는 타입 변수를 정의합니다.
- 코드의 재사용성을 높이고 타입을 안전하게 유지할 수 있도록 도와줍니다.
Generics의 사용 예시
1. 함수에서의 사용
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("Hello World");
let output2 = identity<number>(42);
console.log(output1); // "Hello World"
console.log(output2); // 42
- identity 함수는 제네릭 타입 변수 T를 사용하여 입력과 출력의 타입을 동일하게 유지합니다.
- identity<string>은 문자열을 입력받아 반환하고, identity<number>는 숫자를 입력받아 반환합니다.
2. 클래스에서의 사용
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;
console.log(myGenericNumber.add(myGenericNumber.zeroValue, 5)); // 5
- GenericNumber 클래스는 제네릭 타입 변수 T를 사용하여 숫자형 데이터를 처리합니다.
- zeroValue와 add 메서드는 타입 T를 기반으로 합니다.
3. 인터페이스에서의 사용
interface KeyValuePair<K, V> {
key: K;
value: V;
}
let kvp: KeyValuePair<string, number> = { key: "age", value: 30 };
console.log(kvp.key); // "age"
console.log(kvp.value); // 30
- KeyValuePair 인터페이스는 두 개의 제네릭 타입 변수 K와 V를 사용하여 키-값 쌍을 정의합니다.
- kvp 객체는 문자열 키와 숫자 값을 가집니다.
TypeScript Utility Types
Utility Types란?
- TypeScript는 여러 유용한 유틸리티 타입을 제공하여 기존 타입을 변환하거나 조작할 수 있습니다.
- 유틸리티 타입은 주로 기존 타입에서 부분적으로 변경하거나 일부를 선택하여 새로운 타입을 만드는 데 사용됩니다.
주요 유틸리티 타입과 예시
1. Partial<T>
- 모든 프로퍼티를 선택적으로 만드는 타입입니다.
interface User {
name: string;
age: number;
email: string;
}
let partialUser: Partial<User> = {
name: "John"
};
console.log(partialUser); // { name: "John" }
- Partial<User> 타입은 User 인터페이스의 모든 프로퍼티를 선택적으로 만듭니다.
2. Required<T>
- 모든 프로퍼티를 필수적으로 만드는 타입입니다.
interface User {
name?: string;
age?: number;
email?: string;
}
let user: Required<User> = {
name: "John",
age: 30,
email: "john@example.com"
};
console.log(user); // { name: "John", age: 30, email: "john@example.com" }
- Required<User> 타입은 User 인터페이스의 모든 프로퍼티를 필수적으로 만듭니다.
3. Readonly<T>
- 모든 프로퍼티를 읽기 전용으로 만드는 타입입니다.
interface User {
name: string;
age: number;
email: string;
}
let readonlyUser: Readonly<User> = {
name: "John",
age: 30,
email: "john@example.com"
};
// readonlyUser.age = 31; // 오류: 'age'은 읽기 전용 프로퍼티입니다.
console.log(readonlyUser); // { name: "John", age: 30, email: "john@example.com" }
- Readonly<User> 타입은 User 인터페이스의 모든 프로퍼티를 읽기 전용으로 만듭니다.
4. Pick<T, K>
- 특정 프로퍼티만 선택하여 새로운 타입을 만드는 타입입니다.
interface User {
name: string;
age: number;
email: string;
}
let pickedUser: Pick<User, "name" | "email"> = {
name: "John",
email: "john@example.com"
};
console.log(pickedUser); // { name: "John", email: "john@example.com" }
- Pick<User, "name" | "email"> 타입은 User 인터페이스에서 name과 email 프로퍼티만 선택하여 새로운 타입을 만듭니다.
5. Omit<T, K>
- 특정 프로퍼티를 제외하여 새로운 타입을 만드는 타입입니다.
interface User {
name: string;
age: number;
email: string;
}
let omittedUser: Omit<User, "age"> = {
name: "John",
email: "john@example.com"
};
console.log(omittedUser); // { name: "John", email: "john@example.com" }
- Omit<User, "age"> 타입은 User 인터페이스에서 age 프로퍼티를 제외하여 새로운 타입을 만듭니다.
6. Record 타입
- Record 타입은 객체의 키와 값의 타입을 지정할 수 있게 해주는 유틸리티 타입입니다.
type User = {
id: number;
name: string;
};
type UserRecord = Record<number, User>;
const users: UserRecord = {
1: { id: 1, name: "John" },
2: { id: 2, name: "Jane" },
3: { id: 3, name: "Jim" },
};
console.log(users[1]); // { id: 1, name: "John" }
- 이 예시에서 UserRecord는 number 타입의 키를 가지며, 각 키에 매핑된 값은 User 타입입니다.
7. 유니온 타입
- 유니온 타입은 변수나 매개변수가 여러 타입 중 하나일 수 있음을 나타냅니다.
let value: number | string;
value = 42; // OK
value = "Hello"; // OK
// value = true; // Error: Type 'boolean' is not assignable to type 'number | string'.
- value 변수는 number 또는 string 타입을 가질 수 있습니다.
객체의 키들로 유니온 타입 만들기
- 객체의 키들로 유니온 타입을 만드는 것은 매우 유용합니다. 이는 TypeScript의 키워드 keyof를 사용하여 가능합니다.
type User = {
id: number;
name: string;
email: string;
};
type UserKeys = keyof User; // 'id' | 'name' | 'email'
let key: UserKeys;
key = "id"; // OK
key = "name"; // OK
key = "email"; // OK
// key = "age"; // Error: Type '"age"' is not assignable to type 'UserKeys'.
요약
- Generics는 함수, 클래스, 인터페이스에서 타입 변수를 정의하여 코드의 재사용성을 높이고 타입 안전성을 유지합니다.
- Utility Types는 기존 타입을 변환하거나 조작하여 새로운 타입을 만드는 데 사용됩니다. 주요 유틸리티 타입에는 Partial, Required, Readonly, Pick, Omit 등이 있습니다.