인덱스 시그니쳐(Index Signature)는 {[key : T] : U}형식으로 객체가 여러 Key를 가질 수 있으며 Key와 매칭되는 value를 가지는 경우 사용한다.
인덱스 시그니처는 객체가 <key, vlaue>형식이며 key와 value의 타입을 정확하게 명시해야하는 경우 사용할 수 있다. (TypeScript는 기본적으로 객체의 프로퍼티를 읽을 때 string타입의 key사용을 허용하지 않는다.)
let obj {
월급 : 200,
보너스 : 200,
인센티브 : 100,
복지포인트 100
}
위와 같이 급여와 관련된 객체가 있고, 객체 내부에 존재하는 속성의 값을 모두 합산해야하는 경우라면 인덱스 시그니쳐를 사용해야한다.
function totalPay (payment : 무슨타입..?){
let total = 0;
for (const key in payment){
total += payment[key];
}
return total
}
totalPay()함수의 인자 payment는 key가 string이고 value가 number 타입인 객체만 허용해야 한다. key가 string타입이 아닌 경우 객체의 속성을 접근하는데 문제가 발생하며, Value가 number타입이 아닌 경우 총 금액을 계산하는데 문제가 발생하기 때문이다.
function totalPay (payment : {[key : string] : number}){
let total = 0;
for (const key in payment){
total += payment[key];
}
return total
}
인덱스 시그니쳐는 속성에 타입을 선언하는 구문과 유사하지만 한 가지 차이점이 존재한다. 속성 이름 대신 대괄호 안에 key타입을 작성하는 것이다.
type userType = {
[key : string] : string
}
let user : userType = {
'마이콜':'사람'
'또치':'타조'
}
type userType = {
[key: string]: string | number | boolean;
}
let user : userType = {
'이름' : '또치'
'나이' : 38
'여자' : true
}
type userType = {
[key: string | boolean]: string; // 에러발생
}
위의 예제처럼 key타입을 string, number 타입이 아닌 타입으로 선언하는 경우 에러가 발생한다.
key타입을 Template literal로 타입을 선언하는 경우
type userInfoType = "name" | "age" | "address";
type userType = {
[key in userInfoType]: string;
};
let user: userType = {
'이름': '또치',
'나이': '38',
'주소': '라스베가스'
};
type userType = {
[key: string]: string;
};
let user: userType = {
이름: "또치",
나이: "38"
};
console.log(user.address);
// undefined
위의 예제는 정상적으로 동작하지만 콘솔에 출력된 user.address를 확인하면 undefined가 출력된다. Index Signature는 key타입을 value타입과 매핑한다. 매핑이 올바르게 되지 않으면 Valure타입이 런타임 시점의 Value타입과 다를 수 있다.
Value의 타입을 좀 더 정확하게 명시하기 위해 undefined를 타입으로 추가한다.
type userType = {
[key: string]: string | undefined;
};
type userType = {
[key: string]: string;
};
let user: userType = {
이름: "도우너",
이름: "또치", // 에러발생
나이: "20"
};