GitHub
©-2 kd02109 All rights reserved.

인덱스 시그니처, 템플릿 리터럴

  • typescript
December 21, 2023

인덱스 시그니처

인덱스 시그니처는 특정 타입의 속성 이름은 알 수 없지만 속성 값의 타입을 알고 있을 때 사용하는 문법이다. 인터페이스 내부에 [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)
타입 가드
인덱스드 엑세스 타입