상세 컨텐츠

본문 제목

이미 선언된 배열 및 객체를 typescript 리터럴로 재활용하기

typescript

by citykim 2023. 8. 21. 22:05

본문

이미 선언된 변수를 리터럴로 변경하는 방법

 

배열을 리터럴로 변경하기

// typeof로 간단하게 할 수 있다
const array = ['a', 'b', 'c'] as const

// 결과물 type ArrayType = "a" | "b" | "c"
type ArrayType = typeof array[number]

배열을 as const을 붙여 타입 추론을 더 정확하게 한뒤 typeof로 배열의 index(number)를 넣어주면 간단하게 할 수있다

 

 

 


객체의 key 또는 value를 리터럴로 변경하기

// keyof typeof로 간단히 할 수 있다
const object = {
  test1: 'aaa'
  test2: 'bbb'
  test3: 'ccc'
} as const

// 결과값 type ObjectType = "test1" | "test2" | "test3"
type ObjectType = keyof typeof object

객체에 as const을 붙여 타입 추론을 정확하게 한뒤 keyof typeof 를 넣어서 간단하게 할 수 있다

 

 

이번에는 value를 추출해보자

// 객체
const object = {
  test1: 'aaa',
  test2: 'bbb',
  test3: 'ccc',
} as const

// 결과값 type ValueOfObject = "aaa" | "bbb" | "ccc"
type ValueOfObject = typeof object[keyof typeof object]

똑같이 as const을 붙이고 typeof를 한 뒤 object에 keyof typeof object 값을 key로 넣어주면 value만 전달받을 수 있다

 

 

 


배열의 객체의 key값을 리터럴로 변경하기

// 데이터
const testData = [
  { test1: 'aaa' },
  { test2: 'bbb' },
  { test3: 'ccc' },
]
// 원하는 결과
type KeyOfTestData = 'test1'|'test2'|'test3'

위와같이 배열 + 객체의 key value의 값중 key를 리터럴로 사용하고 싶을때

 

const testData = [
  { test1: 'aaa' },
  { test2: 'bbb' },
  { test3: 'ccc' },
] as const

우선 as const을 붙여 타입추론을 좀 더 정확하게 하도록 해준다

 

// key를 추출하기 위한 제네릭 유틸리티 타입 선언
type ExtractKeys<T> = T extends { [key: string]: string } ? keyof T : never

제네릭 타입 T가 특정 조건(삼항연산자)을 만족하는지 여부에 따라 다른 타입을 반환하는 구조이다

T extends { [key: string]: string }
T가 객체 타입인지 확인한다.

{ [key: string]: string }은 문자열 키와 string을 가질 수 있는 객체를 나타낸다.

이 조건이 참이면 T는 객체 타입이다

keyof T : never
위에서 확인된 [key: string] 부분을 반환하도록 한다

조건을 통과하지 못하면 never타입이 되므로 타입이 key를 반환하지 않게된다

// 배열의 각 항목을 타입으로 추출한다
type FilterKeys = typeof testData[number]

추출된 값
type FilterKeys = {
    readonly test1: "aaa";
} | {
    readonly test2: "bbb";
} | {
    readonly test3: "ccc";
}

typeof로 testData의 index(number)로 타입 FilterKeys을 추출한다

 

// 유틸리티에 추출한 값을 할당해준다
type KeyOfTestData = ExtractKeys<FilterKeys>

// 최종값
type KeyOfTestData = "test1" | "test2" | "test3"

이후 추출한 값을 유틸리티 제네릭에 넣어주면 최종적으로 배열의 object key값을 리터럴로 사용할 수 있다

 

 

이번에는 반대로 배열의 객체의 value를 리터럴로 선언해보자

 

const testData = [
  { test1: 'aaa' },
  { test2: 'bbb' },
  { test3: 'ccc' },
] as const

// 원하는 결과
type ValueOfTestData = "aaa" | "bbb" | "ccc"

 

type ExtractValue<T> = T extends { [key: string]: infer V } ? V : never

이전과 앞부분은 같은데 infer V로 타입을 추론하도록 추가된다
key라는 이름의 문자열 인덱스 객체의 모든 속성 키가 문자열이고 해당 속성의 값 타입을 infer V를 통해 추론하도록 한다

 

그로인해 infer V가 추론한 V를 반환하도록 한다

 

// 최종값
type ValueOfTestData = ExtractValue<typeof testData[number]>

// 결과값
type ValueOfTestData = "aaa" | "bbb" | "ccc"

typeof를 활용하여 변수의 타입을 가져오는데 이때 변수는 testData 배열의 index(number)값이다

이 값을 최종적으로 유틸리티에 넣어주면 배열의 객체의 value를 리터럴로 활용할 수 있게된다

댓글 영역