| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 공식문서
- MegabyteSchool
- 내일배움카드
- 비전공자
- 자료구조
- 입문
- useRef
- GIT
- 이벤트
- 알고리즘
- Github
- next.js
- 코딩테스트
- 프론트엔드
- TypeScript
- 국비지원교육
- react
- CSS
- 패스트캠퍼스
- useMemo
- 리액트
- 모던 자바스크립트 딥 다이브
- 개발자취업부트캠프
- 프로그래머스
- 개발 공부
- 메가바이트스쿨
- 자바스크립트
- styled-components
- JavaScript
- 모던 딥 다이브 자바스크립트
- Today
- Total
개발 기록 남기기✍️
[TypeScript] 템플릿 리터럴 타입을 키로 갖는 객체 만들기 본문
🚨 마주한 문제
공통코드를 템플릿 리터럴 타입으로 다음과 같이 정의했어요.
type Integer = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
type CODE = `CODE${Integer}${Integer}${Integer}`;
그 중 공통코드 일부를 키로 갖는 객체를 만들려고 했어요.
const 예시객체: Record<CODE, string> = {
CODE001: '테스트',
};
그랬더니 다음과 같은 에러가 터집니다.

예시객체는 CODE000 부터 CODE999까지의 키를 모두 보유한 객체가 되어야 한다는 오류입니다.
1️⃣ 1트
const 예시객체: Partial<Record<CODE, string>> = {
CODE001: '테스트',
};
Partial로 Record를 감싸주면 타입에러는 발생하지 않지만, value에 undefined가 올 수 있게 되어버립니다.
이것은 우리가 의도한 코드가 아니에요. 🥹
문제를 해결하기 위해 분산적인 조건부 타입을 사용해보아요.
✨ 분산적인 조건부 타입
제네릭 타입 위에서 조건부 타입은 유니온 타입을 만나면 분산적으로 동작합니다.
type IsStringType<T> = T extends string ? 'yes' : 'no';
type T1 = IsStringType<string | number>;
// type T1 = string extends string ? 'yes' : 'no' | number extends string ? 'yes' : 'no';
// type T1 = 'yes' | 'no';
한마디로 유니온으로 묶인 타입 하나하나마다 조건부 타입 검사를 하고 그 결과값들을 묶어 다시 유니온으로 반환하는 것입니다.
주의해야 할 점은, 분산 조건부 타입은 naked type parameter가 있을 때만 동작합니다.
naked type parameter : 제네릭 T와 같이 의미가 없는 타입 파라미터를 말하며, 만일 직접 리터럴 타입을 명시하거나 T[]와 같이 변환된 타입 파라미터이면 naked가 아니게 된다.
type T2 = string | number extends string ? 'yes' : 'no';
// type T2 = 'no'
따라서 T2의 경우에는 string | number가 string의 서브셋이 아닌 슈퍼셋이기 때문에 false가 되어 no가 됩니다.
그리고 분산 조건부 타입에서 never 타입으로 분산이 되었을 경우, 해당 타입은 유니온에서 제외시킵니다.
type Never<T> = T extends number ? T : never;
type Types = number | string | object;
type ExcludedType = Never<Types>;
// type ExcludedType = number
분산 조건부 타입에서의 never는 제외를 의미합니다. 따라서 제네릭으로 들어온 타입 중, false를 반환하는 타입은 아예 없애버립니다.
이제, 분산 조건부 타입과 never 타입을 조합해서 우리가 원하는 공통코드 객체의 타입을 만들어봅시다!
✨ 해결
export type CommonCodeRecord<T> = T extends string ? Record<T, string> : never;
const 예시객체: CommonCodeRecord<CODE> = {
CODE001: '테스트',
};
key 값으로 사용할 공통코드의 타입이 string의 서브셋이면 해당 값을 key로 가진 객체를 반환하도록 처리했습니다.
이제 CommonCodeRecord의 타입은 Record<'CODE000', string> 부터 Record<'CODE999', string>까지의 유니온을 가지는 타입이 되어 예시객체의 key에 공통코드 타입만 할당할 수 있음과 동시에 모든 공통코드를 다 입력하지 않아도 타입 에러가 발생하지 않습니다.
이제 원하는 대로 타입이 동작하게 되었어요 야호~
'Front-End > TypeScript' 카테고리의 다른 글
| [TypeScript] TypeScript satisfies 연산자 (0) | 2024.04.29 |
|---|---|
| [TypeScript] Object.keys()의 타입 좁히기 (0) | 2024.04.16 |
| 타입스크립트로 블록체인 만들기 (4) (0) | 2022.12.05 |
| 타입스크립트로 블록체인 만들기 (3) (2) | 2022.12.05 |
| 타입스크립트로 블록체인 만들기 (2) (0) | 2022.12.05 |