프론트엔드 개발자가 될거야./ts

[typescript] 너는 무슨 타입이니? (keyof 연산자, Record<string, boolean>)

정니정은니 2023. 5. 17. 12:40

- previewImage 상태 변수에서 kyc 값에 따라 이미지를 렌더링하는 기능을 구현할 때

interface IPreviewImage {
  advanced: string;
  basic: string;
}

const [previewImage, setPreviewImage] =
    useRecoilState<IPreviewImage>(previewImageState);
    
    
{previewImage[kyc as keyof IPreviewImage] && (
     <Preview
       src={previewImage[kyc as keyof IPreviewImage]}
       alt="Image preview"
     />
)}

 

IPreviewImage 인터페이스와 previewImage 상태 변수를 사용하여 이미지 미리보기를 구현하는 부분이다.
IPreviewImage 인터페이스는 advanced와 basic 두 개의 속성을 갖고 있고 previewImage 상태 변수는 useRecoilState 훅을 사용하여 상태와 상태 업데이트 함수를 가져온다.

그 다음 코드에서는 previewImage 상태 변수에서 kyc 값을 키로 사용하여 해당하는 이미지를 가져오고 있다.
kyc 값은 advanced 또는 basic 중 하나이며, previewImage 객체의 속성에 접근하기 위해 keyof 연산자를 사용했다.

이후, 해당 이미지가 존재하는 경우 <Preview> 컴포넌트를 렌더링한다. 
<Preview> 컴포넌트는 src 속성에 previewImage[kyc as keyof IPreviewImage] 값을 전달한다.

previewImage 객체의 속성에 접근하기 위해 keyof 연산자를 사용하여 타입을 알려주었다는 것이 포인트이다!


- 인터페이스  vs Record<string, boolean>

const [tutorial, setTutorial] = useState({
  first: false,
  second: false,
});

이러한 state가 있을 때 나는 상황에 따라 다 두가지의 방법으로 타입을 지정하곤 한다.

 

1. 속성의 의미를 명확히 알고 있고 재사용성이 필요한 경우 => ITutorial 인터페이스 사용

interface ITutorial {
  first: boolean;
  second: boolean;
}

const [tutorial, setTutorial] = useState<ITutorial>({
  first: false,
  second: false,
});

ITutorial은 first와 second라는 명시적인 속성을 가지고 있으며, 이는 코드의 가독성과 이해를 증가시킨다.

 

2. 동적인 속성이 필요하거나 속성의 의미가 명확하지 않은 경우 => Record<string, boolean> 사용

const [tutorial, setTutorial] = useState<Record<string, boolean>>({
  first: false,
  second: false,
});

특정 속성이 고정되어 있지 않고, 동적으로 변할 경우 Record<string, boolean>을 사용하는 것이 유연성을 제공한다.