능히 해낼 수 있다
230822 TypeScript: 유틸리티 타입 본문
✍️✍️✍️ 위 글은 작성자의 지식습득에 따라 추후 퇴고 될 수 있음을 알려드립니다(피드백 환영).
타입스크립트는 유틸리티 타입(utility type)이라는 특별한 타입을 제공하여 타입 정의를 간소화하고 재사용성을 높여주는 기능을 제공한다. 이러한 유틸리티 타입들은 이미 정의된 기존 타입을 변환하거나 결합하여 새로운 타입을 생성하는 데 사용되며, 유틸리티 타입을 사용하면 타입 코드를 더 간결하게 작성하고 중복을 줄이며 유지보수성을 향상시킬 수 있다.
1. keyof
keyof는 TypeScript에서 사용되는 유틸리티 타입 중 하나로 객체 타입의 모든 키를 유니언 타입으로 추출할 수 있다. 주로 제네릭 타입 및 인덱스 시그니처와 함께 사용되어 타입 안전성을 확보하고 동적으로 속성 이름에 액세스할 때 유용하다.
type Person = {
name: string;
age: number;
address: string;
};
//Person 객체 타입의 키를 추출하기위해 keyof를 사용하여 PersonKey 타입을 정의
type PersonKey = keyof Person; // "name" | "age" | "address" 이것과 똑같음
// PersonKey는 "name", "age", "address"와 같은 문자열 리터럴 유니온 타입이됨
keyof를 사용하면 객체의 속성 이름을 문자열 리터럴로 사용할 수 있으므로, 다음과 같이 동적으로 속성에 접근할 때 유용하다
//getProperty 함수: 객체와 키를 입력으로 받아 해당 키에 대한 값을 반환
// key의 타입이 keyof T와 호환되도록 하여 타입 안전성을 확보
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person: Person = {
name: "Mimi",
age: 28,
address: "123 Main St",
};
const name: string = getProperty(person, "name"); // OK
const age: number = getProperty(person, "age"); // OK
const invalidKey: boolean = getProperty(person, "invalidKey"); // 에러: 유효하지 않은 키 사용
2. Partial <T>
Partial 유틸리티 타입은 프로퍼티를 옵션으로 바꿔주기 때문에 일부만 사용이 가능하다. 그말은 제네릭 타입 T의 모든 속성을 선택적으로 만들어 객체를 부분적으로 업데이트하고자 할 때 유용하다.
type Person = {
name: string;
age: number;
};
const partialPerson: Partial<Person> = { name: "Mimi" }; // age 속성은 선택적으로 변경 가능
3. Required<T>
Required 유틸리티 타입은 Partial과 달리 제네릭 타입 T의 모든 속성을 필수로 만든다.
type PartialPerson = Partial<Person>;
type RequiredPerson = Required<PartialPerson>; // name과 age 모두 필수 속성
4. Readonly<T>
Readonly 유틸리티 타입은 제네릭 타입 T의 모든 속성을 읽기 전용으로 만든다.
type ReadonlyPerson = Readonly<Person>;
const person: ReadonlyPerson = { name: "Mimi", age: 28 };
// person.name = "Bob"; // 에러: 속성 'name'은 읽기 전용
5. Record<K, T>
Record 유틸리티 타입은 키 K와 값(타입) T에 대한 객체를 생성한다. Record의 일반적인 사용 사례는 열거형(enum) 또는 문자열을 키로 사용하여 일련의 값에 이름을 부여하는 것이다. Record를 사용하면 일련의 키-값 쌍을 가지는 타입을 정의할 때 편리하며, 특히 열거형과 함께 사용하면 코드를 더 읽기 쉽게 만들 수 있다.
//type Record<K extends keyof any, T> = {
// [P in K]: T;
//};
// K: 객체의 키 타입을 나타내는 제네릭 매개변수. 일반적으로 문자열, 숫자 또는 열거형 타입 사용
// T: 키에 상응하는 값을 나타내는 제네릭 매개변수.
type Fruit = "apple" | "banana" | "orange"; // 문자열 리터럴 유니온 타입
type FruitPrices = Record<Fruit, number>;
// 각 과일에 대한 가격을 나타내는(저장하는) 객체 생성
const fruitPrices: FruitPrices = {
apple: 1,
banana: 0.5,
orange: 0.75,
};
console.log(fruitPrices.apple); // 1.0
console.log(fruitPrices.banana); // 0.5
console.log(fruitPrices.orange); // 0.75
// 존재하지 않는 과일 접근시 에러 발생
// console.log(fruitPrices.grape); // 에러: 속성 'grape'은(는) 'Fruit'에 없음
6. Omit<T, K>
Omit은 유틸리티 타입은 제네릭 타입 T에서 지정된 키 K를 제외한 모든 속성을 가지는 타입을 생성한다. 또한 객체의 키를 기준으로 속성을 제외할 때 사용된다. Omit은 객체의 속성을 기준으로 타입을 조작하는데 사용되고 특히 객체 타입의 일부 속성을 제거하고자 할 때 유용하다.
type PersonWithoutAge = Omit<Person, "age">;
const personWithoutAge: PersonWithoutAge = { name: "David" }; // age 속성 제외
7. Pick<T, K>
Pick은 주어진 객체 타입에서 특정 속성(키)만 선택하여 새로운 타입을 생성하는데 사용되고 객체의 일부 속성만 사용하며 다른 속성은 제거하고자 할 때 유용하다. Pick은 코드에서 필요한 정보만 추출하여 사용하고자 할 때 특히 유용하고 코드의 타입 안정성을 높이고 불필요한 데이터 유출을 방지하는 데 도움이 된다.
// Pick<T, K>
// T: 속성을 선택할 기존 타입
// K: 선택할 속성(키)을 나타내는 문자열 리터럴 유니온 타입
type Person = {
name: string;
age: number;
address: string;
};
// Pick을 사용해 Person 타입에서 name과 age 속성만 선택하여 새로운 타입을 생성
type PersonInfo = Pick<Person, "name" | "age">;
// PersonInfo 타입은 name과 age 속성만 포함, 다른 속성은 포함되지 않음
const person: PersonInfo = {
name: "Mimi",
age: 28,
};
// address 속성은 사용할 수 없음
// person.address = "123 Main St"; // 에러: 'address' 속성은 'PersonInfo'에 없음
8. Exclude<T, U>
Exclude는 제외할 타입을 명시하여 주어진 유니온 타입에서 특정 타입을 제외하고자 할 때 사용된다. Exclude를 사용하면 코드에서 원치 않는 타입을 제거하여 더 정확한 타입을 만들 수 있다.
// Exclude<T, U>
// T: 원래의 타입(유니온 타입)
// U: T에서 제외하고자 하는 타입
type Animal = "dog" | "cat" | "bird" | "fish";
// "bird"와 "fish"를 제외한 나머지 동물을 나타내는 타입 생성
type MammalOrReptile = Exclude<Animal, "bird" | "fish">;
const pet: MammalOrReptile = "dog"; // OK
// "bird"와 "fish"는 사용할 수 없음
// const bird: MammalOrReptile = "bird"; // 에러: 'bird' 타입은 'MammalOrReptile'에 없음
'개발🌐 > TypeScript' 카테고리의 다른 글
230822 TypeScript: 제네릭 (0) | 2023.08.22 |
---|---|
230817 TypeScript: class (0) | 2023.08.15 |
230815 TypeScript: 리터럴, 유니온, 교차 Type (0) | 2023.08.15 |
230815 TypeScript: 함수 (0) | 2023.08.15 |
230811 TypeScript: Interface (0) | 2023.08.11 |