나 보려고 정리하는 TypeScript 핸드북

YUKI KIM·2022년 2월 11일
2

요즘 타입스크립트 공부 목적으로 타입스크립트를 사용 중인데, 사용할수록 정리하고 기록해두고 싶은 개념이 몇몇 있어서 포스팅 한다. 이 글은 계속 추가해나가야진. 타입스크립트 얼른 익숙해지고 싶다. 아자좌.


Type vs. Interface

type과 interface 키워드는 타입을 정의할 때 사용한다. 보통 React app 내에서는 component에 넘겨주는 props의 타입을 정의하기 위해 아래와 같이 사용하곤 한다.

type GreetingsProps = {       //type 사용해도 정상 작동
  name: string;
};

interface GreetingsProps {   //interface 사용해도 정상 작동
  name: string;
};

const Greetings = ({ name }: GreetingsProps) => (
  <h1>Hello, {name}</h1>
);

이 두 키워드 둘 다 타입 정의라는 비슷한 역할을 하기 때문에 차이점과 언제, 어느 상황에 어떤 키워드를 사용하는 것이 적절할지 짚고 넘어갈 필요가 있다.

타입을 확장하는 방식

interface GreetingsProps2 extends GreetingsProps {
  age: number;
}
type GreetingsProps2 = GreetingsProps & {
  age: number;
};

이미 지정한 타입을 확장하고자 할 때, type은 & 연산자, interface는 extends 키워드를 이용한다. 또한, interface의 경우 동일한 이름으로 다시 interface를 정의해 확장하는 것이 가능하지만 type은 동일한 이름으로 다시 선언할 수 없다.

computed property name

type names = 'firstName' | 'lastName';

type NameTypes = {
  [key in names]: string;
}

const yk: NameTypes = { firstName: 'yuki', lastName: 'kim' };

interface NameInterface {
  [key in names]: string; // error
}

computed property name은 표현식(expression)을 이용해 객체의 key 값을 정의하는 문법이다.

type의 경우, computed property name을 사용한 타입 선언이 가능하지만, interface의 경우는 불가능이다.

언제, 어떤 키워드를 쓸지

결론적으로는, TypeScript 팀에서는 interface의 사용을 권장하고 있다. 확장이 용이하다는 이유에서 인데, 사실상 type과 interface가 큰 성능의 차이를 보이는 것은 아니라고 한다.

따라서 프로젝트 내에서의 정해진 코드 컨벤션에 따라 사용하는 것이 가장 적합할 것이다. (결론이 좀 허무한가. ㅇㅅㅇ)


useRef의 적절한 타입

useRef는 React hook의 일종으로, .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환한다. 자세한 설명은 공식문서에서 확인하도록 하자.

3가지 타입 종류

@types/react의 index.d.ts를 보면 useRef 훅은 3개의 정의가 오버로딩되어있는 것을 확인할 수 있다. 하나씩 살펴보면 다음과 같다.

  • useRef<T>(initialValue: T): MutableRefObject<T>;
    • 인자와 제네릭의 타입이 모두 T이면, MutableRefObject<T>를 반환.
    • MutableRefObject<T>의 경우, current 프로퍼티 자체를 직접 변경 가능.

  • useRef<T>(initialValue: T|null): RefObject<T>;
    • 인자의 타입이 null을 허용하는 경우, RefObject<T>를 반환.
    • RefObject<T>는 current 프로퍼티를 직접 수정할 수 없다.

  • useRef<T = undefined>(): MutableRefObject<T | undefined>;
    • 제네릭의 타입이 undefined인 경우(타입을 제공하지 않은 경우), MutableRefObject<T | undefined>를 반환.

T로는 보통, HTMLDivElement, HTMLInputElement 같은 엘리먼트 타입이 들어간다.

수정 가능한 RefObject<T>

const inputRef = useRef<HTMLInputElement>(null);

위와 같이 초기에 null로 정의하면 앞서 RefObject<T>는 current 프로퍼티를 수정할 수 없다고 했지만, current.value는 수정이 가능하다.

current 프로퍼티는 읽기 전용이지만, current 프로퍼티의 하위 프로퍼티인 value는 수정 가능하다. 이는 readonly가 shallow 하기 때문이다. 따라서 DOM을 직접 조작하기 위해서는 초깃값에 null을 넣어준다.


레퍼런스

profile
유키링と 욘데 쿠다사이

0개의 댓글