v19.2Latest

TypeScript 사용하기

TypeScript는 JavaScript 코드베이스에 타입 정의를 추가하는 인기 있는 방법입니다. 기본적으로 TypeScript는JSX를 지원하며, 프로젝트에 @types/react@types/react-dom을 추가하여 React Web에 대한 완전한 지원을 얻을 수 있습니다.

설치

모든프로덕션급 React 프레임워크는 TypeScript 사용을 지원합니다. 설치를 위해 프레임워크별 가이드를 따르세요:

기존 React 프로젝트에 TypeScript 추가하기

React의 타입 정의 최신 버전을 설치하려면:

npm install --save-dev @types/react @types/react-dom

다음 컴파일러 옵션을 tsconfig.json에 설정해야 합니다:

  1. domlib에 포함되어야 합니다 (참고:lib옵션이 지정되지 않으면dom이 기본적으로 포함됩니다).
  2. jsx는 유효한 옵션 중 하나로 설정되어야 합니다. 대부분의 애플리케이션에는preserve라이브러리를 게시하는 경우, 어떤 값을 선택할지jsx 문서를 참조하세요.

React 컴포넌트와 함께하는 TypeScript

참고

JSX를 포함하는 모든 파일은.tsx파일 확장자를 사용해야 합니다. 이는 TypeScript에 이 파일이 JSX를 포함하고 있음을 알려주는 TypeScript 전용 확장자입니다.

React와 함께 TypeScript를 작성하는 것은 React와 함께 JavaScript를 작성하는 것과 매우 유사합니다. 컴포넌트 작업 시 주요 차이점은 컴포넌트의 props에 대한 타입을 제공할 수 있다는 점입니다. 이러한 타입은 정확성 검사와 편집기에서의 인라인 문서화에 사용될 수 있습니다.

빠른 시작 가이드의MyButton 컴포넌트를 예로 들어, 버튼의title을 설명하는 타입을 추가할 수 있습니다:

참고

이 샌드박스들은 TypeScript 코드를 처리할 수 있지만, 타입 검사기를 실행하지는 않습니다. 즉, TypeScript 샌드박스를 수정하여 학습할 수는 있지만, 타입 오류나 경고는 받지 못합니다. 타입 검사를 받으려면TypeScript Playground를 사용하거나 더 완전한 기능을 갖춘 온라인 샌드박스를 사용할 수 있습니다.

이 인라인 구문은 컴포넌트에 타입을 제공하는 가장 간단한 방법이지만, 설명할 필드가 몇 개 생기기 시작하면 다루기 어려워질 수 있습니다. 대신, 컴포넌트의 props를 설명하기 위해interfacetype을 사용할 수 있습니다:

컴포넌트의 props를 설명하는 타입은 필요에 따라 간단하거나 복잡할 수 있지만, 일반적으로type또는interface로 설명된 객체 타입이어야 합니다. TypeScript가 객체를 어떻게 설명하는지는객체 타입에서 배울 수 있으며, 몇 가지 다른 타입 중 하나일 수 있는 prop을 설명하기 위해유니언 타입을 사용하는 데 관심이 있을 수 있고, 더 고급 사용 사례는타입으로부터 타입 생성하기가이드에서 확인할 수 있습니다.

훅 예시

내장 훅에 대한 타입 정의는@types/react에 포함되어 있으므로, 추가 설정 없이 컴포넌트에서 사용할 수 있습니다. 이들은 컴포넌트에서 작성한 코드를 고려하도록 구축되어 있어, 많은 경우추론된 타입을 얻게 되며, 이상적으로는 타입을 제공하는 세부 사항을 처리할 필요가 없습니다.

그러나 훅에 타입을 제공하는 방법에 대한 몇 가지 예시를 살펴볼 수 있습니다.

useState

예를 들어:

이렇게 하면 enabledboolean타입이 할당되고,setEnabledboolean 인수를 받거나 boolean을 반환하는 함수를 받는 함수가 됩니다. 상태에 대해 명시적으로 타입을 제공하려면,useState호출에 타입 인수를 제공하면 됩니다:

이 경우에는 그다지 유용하지 않지만, 타입을 제공하고 싶은 일반적인 경우는 유니언 타입이 있을 때입니다. 예를 들어, 여기서status는 몇 가지 다른 문자열 중 하나일 수 있습니다:

또는, 상태 구조화 원칙에서 권장하는 대로 관련 상태를 객체로 그룹화하고 객체 타입을 통해 다양한 가능성을 설명할 수 있습니다:

useReducer

상태에 대한 타입을 제공하기 위해useReducer호출에 타입 인수를 선택적으로 제공할 수 있지만, 초기 상태에 타입을 설정하는 것이 더 나은 경우가 많습니다:

몇 가지 주요 부분에서 TypeScript를 사용하고 있습니다:

  • interface State는 리듀서 상태의 형태를 설명합니다.
  • type CounterAction는 리듀서에 디스패치될 수 있는 다양한 액션들을 설명합니다.
  • const initialState: State는 초기 상태에 대한 타입을 제공하며, 기본적으로useReducer에서 사용되는 타입이기도 합니다.
  • stateReducer(state: State, action: CounterAction): State는 리듀서 함수의 인수와 반환 값에 대한 타입을 설정합니다.

에 타입을 설정하는 것보다 더 명시적인 대안은useReducer에 타입 인수를 제공하는 것입니다:

useContext

은 컴포넌트 트리 아래로 props를 전달하지 않고도 데이터를 전달하는 기법입니다

컨텍스트가 제공하는 값의 타입은 createContext호출에 전달된 값에서 추론됩니다:

이 기법은 의미 있는 기본값이 있을 때 작동하지만, 때로는 기본값이 없는 경우도 있으며, 그런 경우 기본값으로null이 합리적으로 느껴질 수 있습니다. 그러나 타입 시스템이 코드를 이해할 수 있도록 하려면ContextShape | nullcreateContext에 명시적으로 설정해야 합니다.

이는 컨텍스트 소비자 측에서 타입의| null을 제거해야 하는 문제를 일으킵니다. 우리의 권장 사항은 Hook이 런타임에 존재 여부를 확인하고, 존재하지 않을 때 오류를 던지도록 하는 것입니다:

useMemo

참고

React Compiler는 값과 함수를 자동으로 메모이제이션하여 수동useMemo호출의 필요성을 줄입니다. 컴파일러를 사용하여 메모이제이션을 자동으로 처리할 수 있습니다.

Hook에 타입 인수를 제공하여 더 명시적으로 표현할 수 있습니다

useCallback

참고

React Compiler는 값과 함수를 자동으로 메모이제이션하여 수동useCallback호출의 필요성을 줄입니다. 컴파일러를 사용하여 메모이제이션을 자동으로 처리할 수 있습니다.

은 두 번째 매개변수로 전달된 의존성이 동일한 한 함수에 대한 안정적인 참조를 제공합니다.useMemo와 마찬가지로, 함수의 타입은 첫 번째 매개변수의 함수 반환 값에서 추론되며, Hook에 타입 인수를 제공하여 더 명시적으로 표현할 수 있습니다.

TypeScript strict 모드에서 작업할 때useCallback은 콜백의 매개변수에 대한 타입을 추가해야 합니다. 이는 콜백의 타입이 함수의 반환 값에서 추론되며, 매개변수가 없으면 타입을 완전히 이해할 수 없기 때문입니다.

코드 스타일 선호도에 따라, React 타입의*EventHandler함수를 사용하여 콜백을 정의하는 동시에 이벤트 핸들러의 타입을 제공할 수 있습니다:

유용한 타입

React와 TypeScript가 어떻게 상호작용하는지 익숙해지면 읽어볼 가치가 있는,@types/react패키지에서 제공하는 상당히 광범위한 타입 세트가 있습니다. 이 타입들은DefinitelyTyped의 React 폴더에서찾을 수 있습니다. 여기서는 더 일반적인 타입 몇 가지를 다루겠습니다.

DOM 이벤트 타이핑

React에서 DOM 이벤트를 다룰 때, 이벤트의 타입은 종종 이벤트 핸들러에서 추론될 수 있습니다. 그러나 이벤트 핸들러에 전달할 함수를 추출하려는 경우에는 이벤트의 타입을 명시적으로 설정해야 합니다.

React 타입에는 많은 종류의 이벤트가 제공됩니다. 전체 목록은여기에서 확인할 수 있으며, 이는DOM에서 가장 많이 사용되는 이벤트를 기반으로 합니다.

찾고 있는 타입을 결정할 때는 먼저 사용 중인 이벤트 핸들러에 대한 호버 정보를 살펴볼 수 있으며, 이는 이벤트의 타입을 보여줍니다.

이 목록에 포함되지 않은 이벤트를 사용해야 하는 경우, 모든 이벤트의 기본 타입인React.SyntheticEvent타입을 사용할 수 있습니다.

자식 요소 타이핑

컴포넌트의 자식 요소를 설명하는 데는 두 가지 일반적인 방법이 있습니다. 첫 번째는 JSX에서 자식으로 전달될 수 있는 모든 가능한 타입의 유니온 타입인React.ReactNode 타입을 사용하는 것입니다:

이는 자식 요소에 대한 매우 광범위한 정의입니다. 두 번째는 문자열이나 숫자와 같은 JavaScript 원시 타입이 아닌 JSX 요소만을 포함하는React.ReactElement 타입을 사용하는 것입니다:

주의할 점은, TypeScript를 사용하여 자식 요소가 특정 유형의 JSX 요소라고 설명할 수 없으므로, 타입 시스템을 사용하여<li>자식 요소만을 허용하는 컴포넌트를 설명할 수 없다는 것입니다.

두 가지 React.ReactNodeReact.ReactElement의 예시를 타입 검사기와 함께이 TypeScript 플레이그라운드에서확인할 수 있습니다.

스타일 프로퍼티 타이핑

React에서 인라인 스타일을 사용할 때,React.CSSProperties를 사용하여 style프로퍼티에 전달되는 객체를 설명할 수 있습니다. 이 타입은 모든 가능한 CSS 프로퍼티의 유니온이며,style프로퍼티에 유효한 CSS 프로퍼티를 전달하고 있는지 확인하고, 에디터에서 자동 완성을 받는 좋은 방법입니다.

추가 학습

문서의 개별 API 페이지에는 TypeScript와 함께 사용하는 방법에 대한 더 심층적인 설명이 포함되어 있을 수 있습니다.

다음 자료를 추천합니다:

  • TypeScript 핸드북은 TypeScript의 공식 문서로, 대부분의 주요 언어 기능을 다룹니다.
  • TypeScript 릴리스 노트는 새로운 기능을 깊이 있게 다룹니다.
  • React TypeScript 치트시트는 React와 함께 TypeScript를 사용하기 위한 커뮤니티에서 관리하는 치트시트로, 많은 유용한 예외 사례를 다루며 이 문서보다 더 넓은 범위를 제공합니다.
  • TypeScript 커뮤니티 Discord는 TypeScript 및 React 관련 문제에 대해 질문하고 도움을 받을 수 있는 좋은 장소입니다.