Object.Keys()는 정말 자주 사용하는 함수로 객체에서 키 값을 string으로 가져와 다양하게 이용하는 함수이다.
하지만 string으로 가져와서 TypeScript에서 키값을 이용해 객체에 접근할 때 에로 사항이 있다. 이럴때 사용하기 좋은 것이 바로 as Array<keyof typeof 객체> 이다.
개발하며 아래와 같이 영문으로 된 데이터의 키를 한글로 바꾸어 테이블의 헤더를 구성하려했다.
export const foodHeaderObj = {
foodid: "번호",
name: "이름",
categorie: "상세 분류",
energy: "칼로리",
moisture: "수분",
protein: "단백질",
phosphorus: "인",
potassium: "칼륨",
natrium: "나트륨",
};
아래처럼 진행하면 오류가 발생한다. Object.keys의 반환값은 string[]이기 때문이다. 그래서 위에서 설명한것 처럼 Type Assertion을 이용해야한다. Type Assertion은 시스템이 추론한 타입을 우리가 다시 알려주는 방식이다.
{Object.keys(foodList[0]).map(
(thName) => (
<th>{foodHeaderObj[thName]}</th>
)
)}
{(Object.keys(foodList[0]) as Array<keyof typeof foodHeaderObj>).map(
(thName) => (
<th>{foodHeaderObj[thName]}</th>
)
)}
하지만 그렇게 좋은 방법은 아니다 협업을 하거나 나중에 코드를 리펙토링 하며 발생하는 변경에 유연하게 대처하지 못한다. 예를 들어 foodList의 객체들이 변하거나 foodHeaderObj가 변하면 원하지 못한 결과가 나올 수 있다.
또다른 방법으로는 함수를 만들어 정확한 keys을 가져오는 방식이다.
아래방식은 제네릭을 활용한 함수로 오브젝트에서 확장된 T를 이용해서 반환값을 명시해준다.
export const getKeys = Object.keys as <T extends object>(
obj: T
) => Array<keyof T>;