[타입시스템 15] 인덱스 시그니처
2022. 7. 19. 23:38ㆍ책/이펙티브 타입스크립트
1. 인덱스 시그니처
- { [ key :T ] :U } 형식으로 객체가 여러 키를 가질 수 있게 선언하는 타입을 말한다
- 이때 key의 타입은 string, number, symbol의 조합만 가능하다(보통 string 씀)
- 동적인 데이터의 타입을 정하기엔 좋으나 타입으로서는 부정확하다
- 따라서 런타임 때까지 객체의 속성을 알 수 없는 경우에만 인덱스 시그니처를 사용하자
2. 인덱스 시그니처 대안
사실 런타임 때까지 객체의 프로퍼티를 죽어도 모르겠다면 딱히 대안이랄 게 없다. 다만 a, b, c, d, e,... 정도 선에서 걸러낼 수 있다면 정확한 타입 선언을 위해 최대한 머리를 굴려봐야 한다.
2.1 선택적 필드(or 유니온 타입)
// 이렇게 너무 광범위하게 지정하는것 보단
// a,b,c,d,e, ... 선에서 정리되는 수준이라면
// 아래처럼 선언하는게 차라리 낫다
interface Row { [column :string] :number };
interface Row { a :number; b? :number; c? :number; d? :number; }
2.2 Record <K, T> 사용하기
<K> 타입의 프로퍼티 키를 가지며, 그 값이 <T> 타입인 객체 타입을 반환한다.
// 결과적으론 1번 예시와 같지만 좀더 간단하게 선언하는 방법이다
type RowKey = 'x' | 'y' | 'z';
type Row = Record<RowKey, number>;
2.3 매핑된 타입 사용하기
결국 2.1, 2.2 예시와 같은 내용이지만 키마다 별도의 타입을 지정할 수 있어 쓰기에 따라선 활용도가 더 높을 수 있다.
type Row = {
[key in 'a' | 'b' | 'c'] : key extends 'b' ? string : number;
}
3. 결론
다시 한번 말하지만 런타임 때까지 타입을 죽어도 알 수 없다면 인덱스 시그니처를 쓰는 게 맞다. 그러나 얼추 추론이 가능하다면 최대한 명시적으로 타입을 선언해야 한다.
'책 > 이펙티브 타입스크립트' 카테고리의 다른 글
[타입시스템 18] 매핑된 타입으로 값 동기화 (0) | 2022.07.21 |
---|---|
[타입시스템 17] readony 변경 방지 (0) | 2022.07.20 |
[타입시스템 14] 반복 줄이기(타입연산, 제네릭) (0) | 2022.07.19 |
[타입시스템 13] Type vs Interface (0) | 2022.07.18 |
[타입시스템 12] 함수 표현식에 타입 적용하기 (0) | 2022.07.18 |