ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인덱스 시그니처
    Front-end/TypeScript 2021. 12. 28. 07:54

    인덱스 시그니처

    [property: string] : string 

     1. 키의 이름은 타입 체커에서는 사용하지 않는다

    2. 키의 타입은 string / number / symbol 의 조합이여야하지만 보통은 string 을 사용

    3. 값의 타입은 어떤 것이든 될 수 있다. 

     

    타입에 인덱스 시그니처를 사용하여 유연하게 데이터를 표현할 수 있다. 

    type Contract = {[property: string]: string}
    const contract: Contract = {
      name: '20211228-contract',
      price: '3400000',
      partner: 'madison'
    }

     

    하지만 이렇게 타입 체크가 수행되면 몇가지 단점이 나타난다.

    1. 잘못된 키를 허용하여 name대신 Name으로 작성해도 유효한 Contract 타입이 된다.

    2. 특정 키가 필요하지 않음. ( {}도 유효한 타입이 될수 있다) 

    3.키마다 다른 타입을 가질 수 없다. 

    4. name: 을 입력할때 키 값 (name)에 대한 자동완성 기능이 동작하지 않는다. 

     

    인덱스 시그니처는 동적 데이터를 표현할때 사용하기 

    CSV파일처럼 헤더 row와 column 이 있고 데이터 행을 열 이름과 값으로 매핑하는 객체로 나타내는 경우 인덱스 시그니처를 사용한다. 

    만약 열 이름을 알고 있는 특정한 상황에서는 타입을 사용해야 한다. 선언해둔 열들이 런타임에 일치한다는 보장이 안되어 우려가 된다면 상황에 맞게 판단하여 값 타입에 undefined를 추가한다. 

    연관배열의 경우, 객체에 인덱스 시그니처를 사용하는 대신 Map타입을 사용하는걸 고료할 ㅅ ㅜ있다. 

     

    필드가 제한되어있는 타입인 경우

    interface Row1 { [column: string] : number } // 광범위 
    interface Row2 { a ; number; b?: number; c?:number } // 최선
    type Row3 = 
       | {a : nubmer }
       | {a : number; b: number; }
       | {a : number; b: number; c: number; } // 가장 정확하지만 사용하기 번거로움

     

    너무 번거롭다면 다음 두 가지 대안을 사용할 수 있다. 

    1. Record를 사용하는 방법 

    type Vec3D = Record<'x' | 'y' | 'z', number>;

    2. 매핑된 타입을 사용하는 방법 

    type Vec3D = {[k in 'x' | 'y' | 'z']: number } 
    
    type ABC = {[k in 'a' | 'b' | 'c'] : k extends 'b' ? string : number }

     

     

     

    출처 : 이펙티브 타입스크립트, 타입스크립트 공식문서 

Designed by Tistory.