StudyForYou / ouahhan-typescript-with-react

우아한 타입스크립트 with 리액트 스터디 레포 🧵
4 stars 0 forks source link

#27 [9장_1] useRef 사용 시에 제네릭 타입으로 HTMLInputElement을 사용하는 것과 null에 관한 문제 #42

Closed hyeyoonS closed 2 months ago

hyeyoonS commented 2 months ago

❓문제

const ref = useRef<HTMLInputElement>(null)

처럼 제네릭 타입으로 HTMLInputElement을 사용했는데,

1) 초기값으로 null을 지정할 수 있는 이유가 무엇인가요? 2) 또한 초기값으로 undefined가 아니라 굳이 null을 사용하는 이유는 무엇인가요?

🎯답변

useRef의 타입 종류를 살펴보겠습니다.

const ref = useRef<HTMLInputElement>(null);

function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T | null): RefObject<T>;
function useRef<T = undefined>(): MutableRefObject<T | undefined>;

 interface MutableRefObject<T> {
   current: T;
 }

interface RefObject<T> {
  readonly current: T | null;
}

useRef는 여러 함수 시그니처가 오버로딩되어 있고, 제네릭과 초기 값에 따라 어떤 함수 시그니처에 속하는지 결정되는 형태입니다. 이 때 제네릭으로 HTMLInputElement, 초기 값으로 null을 설정하면 두 번째 시그니처를 만족할 수 있고, 반환 타입이 RefObject 이 됩니다. 만약 초기 값을 undefined로 했다면 세 번째 시그니처를 만족하므로 반환 타입이 MutableRefObject이 될 것입니다. 이 때 MutableRefObject과 RefObject 정의에서 볼 수 있듯 RefObject의 current는 readonly 이므로 값을 변경할 수없고, MutableRefObject의 current는 값을 변경할 수 있습니다. 따라서 MutableRefObject는 current가 바뀌는 사이드 이펙트가 발생할 수 있고, RefObject가 더 안전한 타입이라고 볼 수 있습니다. 그래서 초기 값으로 undefined보다는 null을 사용하는 편이 좋다고 볼 수 있습니다.

drizzle96 commented 2 months ago

useRef의 타입 종류를 살펴보겠습니다.

const ref = useRef<HTMLInputElement>(null);

function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T | null): RefObject<T>;
function useRef<T = undefined>(): MutableRefObject<T | undefined>;

 interface MutableRefObject<T> {
   current: T;
 }

interface RefObject<T> {
  readonly current: T | null;
}

useRef는 여러 함수 시그니처가 오버로딩되어 있고, 제네릭과 초기 값에 따라 어떤 함수 시그니처에 속하는지 결정되는 형태입니다. 이 때 제네릭으로 HTMLInputElement, 초기 값으로 null을 설정하면 두 번째 시그니처를 만족할 수 있고, 반환 타입이 RefObject 이 됩니다. 만약 초기 값을 undefined로 했다면 세 번째 시그니처를 만족하므로 반환 타입이 MutableRefObject이 될 것입니다. 이 때 MutableRefObject과 RefObject 정의에서 볼 수 있듯 RefObject의 current는 readonly 이므로 값을 변경할 수없고, MutableRefObject의 current는 값을 변경할 수 있습니다. 따라서 MutableRefObject는 current가 바뀌는 사이드 이펙트가 발생할 수 있고, RefObject가 더 안전한 타입이라고 볼 수 있습니다. 그래서 초기 값으로 undefined보다는 null을 사용하는 편이 좋다고 볼 수 있습니다.

hyeyoonS commented 2 months ago

초기값으로 null을 지정할 수 있는 이유 & 초기값으로 undefined가 아니라 굳이 null을 사용하는 이유는 무엇인가요?

저는 이렇게 ...쉽게 .... 이해했는데... 아닌가요.....? ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ