TypeScript 13장 - Record type
포스트
취소

TypeScript 13장 - Record type

TypeScript

참고자료1
참고자료2

  • 타입스크립트를 사용하다보니 객체에 담겨있는 keyvalue를 가져와서 사용할 일이 생겼다.
  • 인덱스 시그니처 타입을 사용하다보니 Record Type에 대해 알게 됐고, 더 찾아보기로 하였다.

인덱스 시그니처(index signature)

  • 인덱스 시그니처 타입은 [Key:U]:T 형식의 객체로 여러 key를 가질 수 있으며, key와 매핑되는 value를 가지는 경우 사용한다.
  • 객체가 <Key, Value> 형식으로 정확하게 KeyValue의 타입을 명시해야 되는 경우 사용된다.
  • key 타입은 string|number|symbol|Template literal 타입만 가능하다.
  • 매핑이 올바르지 않고 존재하지 않는 속성으로의 접근이 가능하기 때문에 런타임 시점의 타입과 다를 수 있다.
1
2
3
4
5
6
7
8
9
10
// 타입이 없을 시
const example = {
    example1 : "예시입니다.",
    example2 : "예시입니다."
}

// type err
Object.keys(example).map((list, idx) => (
    ...
))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 인덱스 시그니처 사용
type ExampleSignature = {
    [key: string] : string
}

const example: ExampleSignature = {
    example1 : "예시입니다.",
    example2 : "예시입니다.",
}

// type ok
Object.keys(example).map((list, idx) => (
    ...
))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 존재하지 않는 속성
type UndefinedProperty = {
    [key: string] : string
}

const example: UndefinedProperty = {
    example1: "예시입니다.",
    example2: "예시입니다.",
}

// type ok
Object.keys(example).map((list, idx) => (
    ...
))

console.log(example.example3); // undefined

Record Type

  • 타입스크립트 2.1에 도입된 유틸리티 타입이다.
  • 인덱스 시그니처 타입이 key의 의도를 더 명확하게 나타내지만 Record를 사용하여 더욱 간단한 작성이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
type ExampleSignature = {
  [key: string]: string,
};

const example: ExampleSignature = {
  example1: "예시입니다.",
};

const sameExample: Record<string, string> = {
  example1: "예시입니다.",
};

Record 문자열 리터럴

  • 인덱스 시그니처 타입과 유사하게 사용이 가능하지만 key로 문자열 리터럴을 사용할 수 있는 유틸리티 타입이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
// 문자열 리터럴 에러
// type err
// index signature paramerter ... cannot be literal type
type LiteralSignature = {
    [key: "example1"|"example2"|...]: string;
}

type Example = "example1"|"example2"|...

type RecordExample = Record<Example, strirng>

// type ok
const example: RecordExample = {...}

2.9버전의 열거형

  • 2.9부터는 문자열 리터럴보다 깔끔한 열거형을 key로 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 2.9 열거형
type Example = {
  1: "example1",
  2: "example2",
  3: "example3",
};

type RecordExample = Record<Example, string>;

const example: RecordExample = {
  example1: "예시입니다.",
  example2: "예시입니다.",
  example3: "예시입니다.",
};

keyof와 Record

  • 타입 또는 인터페이스에 존재하는 모든 키 값을 union 형태로 가져온다.
1
2
3
4
5
6
7
8
9
10
11
type Example = {
    example1: string;
    example2: string;
    example3: string;
}

type RecordExample = Record<keyof Example, string>;

const example: RecordExample = {
    ...
}

활용

  • 인터페이스 타입인 경우 타입 키워드를 사용하는 것과 달리 속성을 따로 지정해서 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
interface ExampleKey {
    exampel1: string;
    example2: string;
}

interface ExampleValue {
    exArr1: string;
    exArr2: string;
}

// type err
interface WrongExampleType {
    [K in keyof ExampleKey]: ExampleValue[]
}

// type err
const example:{[K in keyof ExampleKey]: ExampleValue[]} = {...}

// 속성 접근
// type ok
interface TypeExample {
    example: {
        [K in keyof ExampleKey]: ExampleValue[]
    }
}

const example: TypeExample = {
    example: {
        example1 : [exArr1, exArr2],
        example2 : ...,
    }
}

const example: TypeExample["example"] = {
    example1: [exArr1, exArr2],
    example2: ...,
}
1
2
3
4
// Record
const example: Record<keyof ExampleKey, ExampleValue[]> = {
    example1: [exArr1, exArr2],
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.