인덱스 시그니처, 템플릿 리터럴
인덱스 시그니처
인덱스 시그니처는 특정 타입의 속성 이름은 알 수 없지만 속성 값의 타입을 알고 있을 때 사용하는 문법이다. 인터페이스 내부에 [key: K]: T
꼴로 타입을 명시해주면 되는데, 이는 해당 타입의 속성 키는 모두 K 타입이어야 하고 속성값은 모두 T 타입을 가져야 한다는 의미다.
인덱스 시그니처를 선언할 때 다른 속성을 추가로 명시해줄 수 있는데 이때 추가로 명시된 속성은 인덱스 시그니처에 포함되는 타입이어야 한다.
interface indexSignatureEx {
[key: string]: boolean | number;
length: number;
isValid: boolean;
name: string; // 에러 발생
/* Property 'name' of type 'string' is not assignable to
'string' index type 'number | boolean'. */
}
Mapped types
다른 타입을 기반으로 한 타입을 선언할 때 사용합니다. 특히 인덱스 시그니처 문법을 사용해서 반복적인 타입 선언을 효과적으로 줄일 수 있습니다.
type User = {
name: string;
age: number;
};
type Mapped<T> = { [key in keyof T]?: T[key] };
const nameExample: Mapped<User> = { name: 'son' };
const ageExample: Mapped<User> = { age: 12 };
const nameAndAgeExample: Mapped<User> = { name: 'son', age: 28 };
Mapped 타입에서 mapping 작업을 진행 할 때에, readonly
와 ?
수식어로 적용할 수 있습니다. Mapped 타입에서는 readonly
나 ?
앞에 -
를 붙여주어 해당 수식어를 제거할 수 있습니다.
type User = {
readonly name: string;
readonly age: number;
};
type MappedMutable<T> = { -readonly [key in keyof T]?: T[key] };
const nameExample: MappedMutable<User> = { name: 'son' };
const ageExample: MappedMutable<User> = { age: 12 };
nameExample.name = 'in';
ageExample.age = 20;
ageExample.name = 'Hwang';
mapped type은 다음과 같은 반복적인 상황을 해결할 수 있습니다.
const END_POINT = Object.freeze({
postStarting: '/user/starting',
getMbtmi: '/user/mbtmi',
getAnswerVisiting: '/answer/visiting',
userNumber: '/user/number',
postResult: '/user/answers',
patchMbti: `/user/mbti`,
});
type ID = keyof typeof END_POINT; // ID 값만 추출
/*
"postStarting" | "getMbtmi" | "getAnswerVisiting" |
"userNumber" | "postResult" | "patchMbti"
*/
type MakeCheck = {
[key in ID as `${key}_mutable`]: {
method: string;
sucess?: boolean;
};
};
/*
type MakeCheck = {
postStarting_mutable: {
method: string;
sucess?: boolean | undefined;
};
getMbtmi_mutable: {
method: string;
sucess?: boolean | undefined;
};
getAnswerVisiting_mutable: {
method: string;
sucess?: boolean | undefined;
};
userNumber_mutable: {
method: string;
sucess?: boolean | undefined;
};
postResult_mutable: {
method: string;
sucess?: boolean | undefined;
};
patchMbti_mutable: {
method: string;
sucess?: boolean | undefined;
};
}
*/
템플릿 리터럴 타입(Template Literal Types)
템플릿 리터럴 타입은 자바스크립트의 템플릿 리터럴 문자열을 사용하여 문자열 리터럴 타입을 선언할수 있는 문법입니다.
type Query = 'user/like' | 'user/login' | 'user/token';
type TOTAL_URL = `https://www.main.com/${Query}`;
/*
type TOTAL_URL = "https://www.main.com/user/like"
| "https://www.main.com/user/login" | "https://www.main.com/user/token"
*/
위의 예시와 같이 리터럴 유니온 타입인 Query를 넣게 된다면, 각 멤버들이 차례대로 해당 변수에 들어가서 https://www.main.com/
이 들어간 새로운 문자열 리터럴 유니온 타입을 만들 수 있습니다.
Content Table
- 인덱스 시그니처
- Mapped types
- 템플릿 리터럴 타입(Template Literal Types)