SlideShare a Scribd company logo
1 of 88
Download to read offline
Codeitmall 타입스크립트 마이그레이션
2023.06.08 이정환
목차
1. 프로젝트에 타입스크립트 세팅하기
• 타입스크립트 관련 라이브러리 설치하기
• 타입스크립트 컴파일러 옵션 설정하기
2. 페이지 단위로 타입스크립트 적용하기
• index 페이지
• search 페이지
• setting 페이지
• items/ id 페이지
• 그 외의 페이지들
3. 컴포넌트 단위로 타입스크립트 적용하기
• Button 컴포넌트
• ButtonLink 컴포넌트
• Container 컴포넌트
1. 프로젝트에 타입스크립트 세팅하기
• 타입스크립트 관련 라이브러리 설치하기
• 타입스크립트 컴파일러 옵션 설정하기
2. 페이지 단위로 타입스크립트 적용하기
• index 페이지
• search 페이지
• setting 페이지
• items/ id 페이지
• 그 외의 페이지들
3. 컴포넌트 단위로 타입스크립트 적용하기
• Button 컴포넌트
• ButtonLink 컴포넌트
• Container 컴포넌트
패키지에 타입스크립트 관련 라이브러리 추가하기
npm i save dev typescript types/react types/node
설치하는 라이브러리 별 의미는 다음과 같습니다.
• typescript : 타입스크립트 라이브러리 tsc를 포함하고 있음
• types/react : react 내장 기능들의 타입 정보를 가지고 있는 라이브러리
• types/node : node 내장 기능들의 타입 정보를 가지고 있는 라이브러리
패키지에 타입스크립트 관련 라이브러리 추가하기
npm i save dev typescript types/react types/node
types/next는 왜 설치하지 않나요?
• types/* 패키지들은 JS로 작성된 라이브러리들의 타입 정보만을 담고있는 패키지임 Definitely Typed
• nextjs 또한 자바스크립트로 만들어졌기에 이전에는 types/next가 존재했음
• 그러나 현재에는 nextjs에 타입 선언 파일이 자체적으로 포함되므로 따로 설치할 필요가 없음
패키지에 타입스크립트 관련 라이브러리 추가하기
npm i save dev typescript types/react types/node
save dev 옵션을 사용하는 이유
• 모든 타입스크립트의 타입 관련 코드는 컴파일 이후 사라지게 됨
• 따라서 프로덕션 상황에서는 타입 관련 라이브러리가 필요하지 않음
• 이에 개발 모드에만 사용하는 라이브러리로 설치하기 위해 save dev 옵션을 사용함
타이핑 하기 귀찮다면
-
D 로도 사용할 수 있음
타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기
이미 존재하는 Next.js 프로젝트에 타입스크립트 컴파일러 옵션 설정하기
• 타입스크립트 컴파일러 옵션은 tsconfig.json에 설정함
• 따라서 프로젝트 루트 아래에 tsconfig.json 파일을 생성하고 JSON Format으로 필요한 옵션들을 직접 설정해줘야 함
• 그러나 Next.js 프로젝트를 위해 설정해줘야 할 옵션 들이 너무 많음 매번 프로젝트마다 일일이 설정하기 귀찮음
• 이럴때에는 Next.js에게 타입스크립트를 사용할거라고 알려줘서 자동으로 생성하게 만들 수 있음
자동으로 타입스크립트 컴파일러 옵션 설정하는 방법
1. 최소 하나 이상의 파일이 타입스크립트 확장자 TS, TSX 를 갖도록 파일 생성 또는 변경하기
2. npm run dev 명령을 입력하여 프로젝트를 그냥 실행하기
3. 자동으로 tsconfig.json 파일 생성
타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기
1. 최소 하나 이상의 파일이 타입스크립트 확장자 TS, TSX 를 갖도록 파일 생성 또는 변경하기
• pages/index.js
->
pages/index.tsx로 변경함
• 확장자 변경시 발생하는 오류는 일단 무시해도 됨
타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기
2. npm run dev 명령을 입력하여 프로젝트를 그냥 실행하기
• 오류는 무시하고 터미널에 npm run dev을 명령하여 개발 모드로 프로젝트 실행
• We detected TypeScript in your project and create a tsconfig.json file for you 라는 메세지가 출력됨
• 해석 : 타입스크립트 파일을 너의 프로젝트에서 찾았어 tsconfig.json을 자동으로 만들어줄게 라는 뜻
타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기
3. 자동 생성된 tsconfig.json과 next env.d.ts을 확인하기
• 프로젝트 루트에 다음 파일들이 자동 생성 됨
• next env.d.ts
• tsconfig.json
자동 설정된 컴파일러 옵션 살펴보기
tsconfig.json 파일에 설정된 옵션 살펴보기
• 상당히 많은 개수의 옵션이 자동으로 설정되어 있다.
• 이미 강의에서 다룬 옵션 30 처음 보는 옵션 70 으로 이루어짐
• 이런 옵션들을 모른다고 어디서 잡아가지는 않는다.
• 그러나 우리가 자주 사용하는 도구 React, Next 에서 주로 사용 되는
옵션들이므로 알아두면 꽤 도움이 된다.
자동 설정된 컴파일러 옵션 살펴보기 1/13
lib 옵션
• Library 라는 의미
• 타입스크립트의 컴파일 과정에서 사용될 라이브러리들을 설정하는 옵션
• 배열 형태로 사용할 라이브러리의 이름을 설정
• 각각의 라이브러리는 이름에 맞는 내장 API 들의 타입을 정의함
• dom
:
DOM 관련 타입이 정의되어 있음
• ex window, document, etc
• dom.iterable : 반복 가능한 DOM 요소의 타입들이 정의되어 있음
• ex HTMLCollection, NodeList, CSSRuleList, etc
• esnext : 최신 ecma 스크립트에서 제공하는 자바스크립트 내장 API들에 대한 타입이 정의되어 있음
• ex Promise, Arrow Functions, etc
• * 결론적으로 이 타입스크립트 프로젝트를 컴파일 할 때 dom, dom.iterable, esnext 관련 타입 정보가 필요하다고 설정해 둔 것
자동 설정된 컴파일러 옵션 살펴보기 2/13
allowJS 옵션
• 이미 강의에서 한 번 다룬 적이 있는 옵션
• 타입스크립트 파일 ts, tsx 에서 자바스크립트 파일 js, jsx 를
불러와 사용할 수 있도록 허용하는 옵션
• 이 옵션을 키면 a.ts에서 b.js를 불러 사용가능
• 처음부터 타입스크립트로 프로젝트를 개발하는 경우에는 필요하지 않을 수 있음
• 자바스크립트 파일을 생성하지 않을 것이기 때문에
• 그러나 자바스크립트를 마이그레이션 할 때 매우 유용한 옵션
• 모든 자바스크립트 파일을 한번에 타입스크립트 파일로 바꾸기 어렵기 때문
• 순서대로 하나씩 변경할 때 아주 유용한 옵션
자동 설정된 컴파일러 옵션 살펴보기 3/13
skipLibCheck 옵션
• 선언 파일들의 타입 체킹을 건너뛰는 옵션
• 선언 파일이란? *.d.ts 확장자를 갖는 파일들을 말함
• 이 옵션을 허용하는 이유 컴파일 시간을 줄이기 위해
• 엄밀히 말하자면 타입스크립트 컴파일 타임을 줄이기 위함
• 대다수의 라이브러리들은 d.ts 파일을 통해 타입 정보를 제공함
• 따라서 모든 라이브러리들의 타입 정보를 일일이 검사하면 오래 걸림
자동 설정된 컴파일러 옵션 살펴보기 4/13
strict 옵션
• 엄격한 타입 검사 모드를 설정하는 옵션
• 이 옵션을 키면 아래의 옵션 들도 함께 켜짐
• noImplicitAny : 암시적 any 비 허용
• strictNullChecks : null 타입이 아닌 변수에 null 할당 비 허용
• etc …
• Next.js는 기본적으로 이 옵션을 비활성화 false 로 설정함
• 마이그레이션 과정에서 최대한 유연하게 작동하도록 자동 설정 됨
• 향후 우리가 직접 마이그레이션 할 때에는 활성화 true 할 예정
자동 설정된 컴파일러 옵션 살펴보기 5/13
forceConsistentCasingInFileNames 옵션
• 파일 이름에 일관된 대 소문자를 강제하는 옵션
• 파일 이름에 대소문자를 구별하도록 설정하는 옵션임
ex a.ts
<->
A.ts를 다르게 평가하도록 설정하는 옵션
• 굳이 구별하지 않을 이유가 없음
자동 설정된 컴파일러 옵션 살펴보기 6/13
noEmit 옵션
• 컴파일시 자바스크립트 파일을 생성하지 않도록 설정하는 옵션
• 이 옵션이 활성화 되면 TSC는 타입 체킹만 진행하고 트랜스파일 된 자바스
크립트 코드를 생성하지 않도록 제한 됨
• 이 옵션을 사용하는 이유
• Next.js, Raect.js 프로젝트에서는 Webpack, Vite, Turbopack 등의 번
들러를 이용함
• 이 경우 Babel이나 SWC등의 별도의 트랜스파일러를 이용해 컴파일을 진
행하게 됨
• 타입스크립트를 컴파일하고 나서 별도의 번들링 작업을 추가로 진행하기 때
문에 별도의 자바스크립트 파일을 생성할 필요가 없음
자동 설정된 컴파일러 옵션 살펴보기 7/13
incremental 옵션
• 증분 컴파일 지원할 것인지 결정하는 옵션
• 증분이란 수학적인 용어로 변화한 양을 나타내는 말
• ex 증분 백업 : 변화한 데이터만 별도로 추가 백업하는 방법
• 증분 컴파일이란
• 컴파일 기록을 계속해서 남겨둠으로써 특정 파일에 변화가 발생해 다시 컴
파일 해야 하는 경우 이전의 기록을 토대로 변화한 파일만 다시 컴파일 하
는 방법
• 쉽게 말해 변화한 TS 파일만 다시 컴파일 하게 됨
빠른 컴파일 시간 확보를 위함
자동 설정된 컴파일러 옵션 살펴보기 8/13
esModuleInterop 옵션
• CJS 방식으로 내보낸 값을 ES 방식의 Import로 가져올 수 있도록 해주는 옵션
• CJS로 작성된 모듈로부터 default import를 이용할 수 있음
• ex
• React는 default로 내보낸 값이 없으나 esModuleInterop 설정을 켜주면
import React from react 같은 방식으로 default 값을 가져올 수 있다.
자동 설정된 컴파일러 옵션 살펴보기 9/13
module 옵션
• 컴파일 된 자바스크립트 코드가 사용할 모듈의 버전을 설정하는 옵션
자동 설정된 컴파일러 옵션 살펴보기 10/13
moduleResolution 옵션
• 타입스크립트의 모듈 해석 방식을 결정하는 옵션
• 모듈 해석이란?
• import A from B 일때 B의 위치를 찾는 방식을 의미함
• 타입스크립트는 다음 2가지 모듈 해석 방식을 제공
• Classic 기본값
• Node 권장값
• Classic 방식의 동작
• 절대 경로일 때 프로젝트의 루트에서 모듈을 찾음
• Node 방식의 동작
• 절대 경로일 때 node modules 폴더 아래에서 모듈을 찾음
• 예외적으로 baseURL 또는 paths 설정시 매핑된 경로에서 모듈을 찾음
자동 설정된 컴파일러 옵션 살펴보기 11/13
resolveJsonModule 옵션
• 타입스크립트에서 JSON 파일을 불러오도록 허용하는 옵션
• 불러온 JSON의 형태에 맞게 타입을 자동 추론해주기도 함
자동 설정된 컴파일러 옵션 살펴보기 12/13
isolatedModules 옵션
• 모든 타입스크립트 파일이 독립적인 모듈로 동작하는 것 처럼 컴파일 하는 옵션
• Babel, SWC 등의 TSC가 아닌 컴파일러는 타입스크립트 파일을 파일 별
로 하나 하나 변환하는데 이때 오류가 발생할 수 있는 상황들에 대해 경고
• TS 5.0 이하까지는 모든 파일이 개별 모듈로 취급 되길 강제했으나 이제 그
렇지는 않음
자동 설정된 컴파일러 옵션 살펴보기 13/13
jsx 옵션
• 타입스크립트에서 JSX를 사용하기 위해 설정하는 옵션
Path Alias 설정하기
타입스크립트 환경에서 Path Alias를 적용하기 위해
jsconfig.json 파일에 설정되어 있던 paths 옵션을
tsconfig.json 파일에 그대로 붙여넣기
Strict 모드 켜기
엄격한 타입 검사를 통해 마이그레이션 과정에서 잠재적인 타입오류들을 다 찾아내기 위해 strict 옵션 true로 설정
1. 프로젝트에 타입스크립트 세팅하기
• 타입스크립트 관련 라이브러리 설치하기
• 타입스크립트 컴파일러 옵션 설정하기
2. 페이지 단위로 타입스크립트 적용하기
• index 페이지
• search 페이지
• setting 페이지
• items/ id 페이지
• 그 외의 페이지들
3. 컴포넌트 단위로 타입스크립트 적용하기
• Button 컴포넌트
• ButtonLink 컴포넌트
• Container 컴포넌트
index.tsx
index.tsx 파일에는 index 페이지의 로직이 정의되어 있음
index.tsx
index.js
->
index.tsx
먼저 Home 컴포넌트의 Props 타입 정의가 필요함
props가 암시적 any로 추론되고 있음
props로 부터 구조 분해 할당한 products 또한
any 타입으로 추론 되므로 안전하지 않은 상태
따라서 Products의 타입을 먼저 정의한 다음
Props 타입을 정의 해주어야 함
pages/index.tsx
index.tsx
Product 타입 정의하기
이 타입은 다른 파일에서도 사용할 것으로 예상되므로
types.ts 파일을 만들어 해당 파일 내에 모듈화
/types.ts 새롭게 생성
index.tsx
pages/index.tsx로 돌아와서
1. import 문으로 방금 만든 Product 타입을 불러옴
2. Props 타입을 정의
3. getStaticProps의 반환값 타입을 정의
• Home 컴포넌트가 제공받는 매개변수 props의 값이
이 함수의 리턴값이기 때문
4. Home 컴포넌트의 Props 매개변수 타입 정의
pages/index.tsx
index.tsx
🚨
그러나 이렇게 작성하면 타입으로 인해 추가되는 코드의 양이 꽤 많음
이럴 때 Next.js에서 기본 제공하는 유틸리티 타입인
inferGetStaticPropsType T
>
을 이용하면
좀 더 코드를 클린하게 리팩토링 할 수 있음
pages/index.tsx
index.tsx
pages/index.tsx
좀 더 클린하게 만들어보기 🧹
inferGetStaticPropsType T
>
타입 변수 T에 getStaticProps 함수의 타입을 전달하면
해당 getStaticProps 함수의 props의 타입을 추출하는
Next.js 내장 유틸리티 타입
index.tsx
pages/index.tsx
그런데 이렇게 해주면 추가적인 문제가 생김 🚨
props의 타입이 products를 포함한 객체타입이라는 것
까지는 추론되나, products의 타입이 any로 추론됨
axios.get으로 불러오는 res의 타입이 any이므로
res.data.results에 해당하는 products도 any가 되기 때문
index.tsx
pages/index.tsx
따라서 axios.get의 타입을 정의해줘야 함
axios.get 메서드는 제네릭 함수이므로
호출 시 타입변수 T에 제공한 타입이 곧 반환값의 타입이 됨
그 결과 props의 타입도 잘 추론 됨
index.tsx
lib/api.ts 새로 생성
여기서 추가로 더 클린하게!
getStaticProps 내부의 API 로직을 별도의 파일로 분리
• lib/api.ts 파일을 생성
• 해당 파일 아래에 fetchProducts 함수로 작성
분리
index.tsx
pages/index.tsx
여기서 추가로 더 클린하게!
getStaticProps 내부의 API 로직을 별도의 파일로 분리
• lib/api.ts 파일을 생성
• 해당 파일 아래에 fetchProducts 함수로 작성
• 불러다 사용
index.tsx 리팩토링 완성 🎉
search.tsx
search.tsx 에는 /search 페이지의 로직이 정의되어 있음
search.tsx
search.js
->
search.tsx로 파일명 변경
오류가 발생하는 부분 살펴보기
1. getServerSideProps
• context 매개변수가 암시적 any 타입으로 추론되고 있음
2. Search 컴포넌트
• props가 암시적 any 타입으로 추론되고 있음
하나씩 천천히 수정해보도록 하겠습니다
pages/search.tsx
search.tsx
getServerSideProps 함수의 오류부터 해결
• context 매개변수의 타입을 GetServerSidePropsContext로 정의
pages/search.tsx
node modules/next/types/index.d.ts
search.tsx
getServerSideProps 내부 타입 정의
• context.query q 는 string string undefined 타입으로 추론
• ?q 검색어 : string 타입
• ?q 검색어1 q 검색어2 : string 타입
• q가 없을 경우 : undefined 타입
• stringifiedQuery 변수를 선언해 string 타입으로 좁혀줌
• axios.get 반환값 타입 설정
pages/search.tsx
search.tsx
getServerSideProps에서 비동기 로직 분리
이전에 lib/api.ts에 만들어둔 fetchProducts를 수정하여 함께 사용
pages/search.tsx
lib/api.ts
분리
search.tsx
getServerSideProps에서 비동기 로직 분리
이전에 lib/api.ts에 만들어둔 fetchProducts를 수정하여 함께 사용
pages/search.tsx
lib/api.ts
search.tsx
Search 컴포넌트의 Props 타입 정의
• InferGetServerSidePropsType T
>
타입 으로 정의
• InferGetStaticPropsType T
>
와 유사한 타입
search.tsx 마이그레이션 완료 🎉
pages/search.tsx
setting.tsx
setting.tsx에는 /setting 페이지의 로직이 작성되어 있음
setting.tsx
setting.js
->
setting.tsx로 확장자 변경
이 페이지에서 사용하는 컴포넌트
Dropdown
ThemeContext
컴포넌트들 부터 마이그레이션 하는 방향이 나을 것 같다
pages/setting.tsx
setting.tsx
-
ThemeContext 수정
ThemeContext.js
->
ThemeContext.tsx 로 수정
오류가 발생하고 있는 부분
• 8번 : createContext 함수 호출
• 10번: ThemeProvider 컴포넌트의 props
쉬운 부분, 간단한 부분부터 수정하는 순서로 진행
lib/ThemeContext.tsx
setting.tsx
-
ThemeContext 수정
ThemeProvider 컴포넌트 Props 타입 정의
• ThemeProvider 컴포넌트의 Props 타입 설정
• children 프로퍼티는 ReactNode 타입으로 정의
• ReactNode 타입
• React에서 Node로 분류될 수 있는 모든 타입의 유니언
lib/ThemeContext.tsx
setting.tsx
-
ThemeContext 수정
useState 타입 정의
• theme State는 dark 아니면 light 의 값을 가짐
• useState는 타입 변수가 없으면 초기값을 기준으로 타입을 추론
• theme State의 타입이 기본적으로는 string 타입으로 추론
• 더 정밀한 타입 정의를 위해 Theme 타입을 types.ts에 선언한
다음 useState의 타입 변수로 제공
lib/ThemeContext.tsx
types.ts
setting.tsx
-
ThemeContext 수정
createContext 타입 정의 오류 원인부터 살펴보기
• createContext 메서드를 호출할 때 오류가 발생함
createContext 메서드의 타입 살펴보기
• 타입변수 T를 제공받는 제네릭 함수
• 하나의 필수 매개변수 defaultValue를 제공받음
• 반환값의 타입은 Context T
>
오류 원인
• 필수 매개 변수에 값이 제공되지 않았기 때문
lib/ThemeContext.tsx
types/react 내부에 정의된 createContext T
>
setting.tsx
-
ThemeContext 수정
createContext 타입 정의 타입 정의하기
• theme와 setTheme를 포함한 객체와 null 타입의 유니온 타입
으로 정의함
• theme State의 타입은 Theme로 정의함
• setTheme의 타입은 Dispatch SetStateAction Theme
로 정의함
• Dispatch SetStateAction T
>
>
는 리액트 내장 타입
• theme
:
Theme
=>
void 형태로 정의해도 되지만 함수
형 업데이트 등의 다양한 인터페이스를 제공하기 위해 좀
더 공식적인 방식을 사용함
lib/ThemeContext.tsx
setting.tsx
-
ThemeContext 수정
ThemeContext 마이그레이션 완료 🎉
• 타 컴포넌트에서 불러 사용할 useTheme 의 타입이 잘 추론되
는 걸 확인할 수 있음
lib/ThemeContext.tsx
setting.tsx
-
ThemeContext 수정
setting.tsx로 돌아와 useTheme의 타입이 잘 추론되는지 확인
• theme
:
Theme 타입으로 추론 ✅
• setTheme
:
Dispatch SetStateAction Theme 로 추론 ✅
pages/setting.tsx
setting.tsx
-
Dropdown 컴포넌트 수정
Dropdown.js
->
Dropdown.tsx로 확장자 변경
다양한 곳에서 오류 발생
차례대로 하나 하나 해결해봅시다 😃
components/Dropdown.tsx
setting.tsx
-
Dropdown 컴포넌트 수정
components/Dropdown.tsx
pages/setting.tsx
Dropdown 컴포넌트의 Props 타입 정의
-
Setting 컴포넌트에서 전달하는 Props를 기준으로 정의함
setting.tsx
-
Dropdown 컴포넌트 수정
components/Dropdown.tsx
Dropdown 컴포넌트의 useRef 함수 타입 정의
타입 변수로 HTMLDivElement 설정
이 레퍼런스 객체가 참조할 태그가 div 이기 때문
useRef 메서드의 자세한 타입 정보는 뒷 슬라이드에!
setting.tsx
-
Dropdown 컴포넌트 수정
types/react 내부에 정의된 useRef 함수 타입
React의 useRef의 타입 살펴보기
• 함수 오버로딩이 구현되어 있음
• 동일한 함수에 여러 버전의 타입을 정의해
매개변수의 개수나 타입에 따라
각각 다른 버전의 함수 타입을 사용하게 하는 문법
• 3개의 오버로드 시그니쳐가 존재함
• 3가지 버전으로 사용할 수 있다는 의미
• 타입 변수나 인수로 무엇을 전달하느냐에 따라서
반환하는 RefObject의 타입이 달라짐
이 차이점을 알면 컴포넌트 내부에서 변수로 사용하기 위한 레퍼런스 객체와
DOM Element를 참조하기 위해 사용하는 레퍼런스 객체를 나눠 사용할 수 있게 됨
setting.tsx
-
Dropdown 컴포넌트 수정
types/react 내부에 정의된 useRef 함수 타입
첫번째 오버로드 시그니쳐 살펴보기
하나의 타입 변수 T를 사용하는 제네릭 함수
필수 매개변수 initalValue의 타입은 T
반환값의 타입 MutableRefObject T
>
MutableRefObjecT
<
T
>
타입
레퍼런스 객체의 current 프로퍼티의 값 수정 가능
current 프로퍼티의 타입은 T
다음과 같이 컴포넌트 내부에서 변수의 역할을 수행할
레퍼런스 객체를 만들때 사용하면 좋다
MutableRefObject T
>
setting.tsx
-
Dropdown 컴포넌트 수정
types/react 내부에 정의된 useRef 함수 타입
두번째 오버로드 시그니쳐 살펴보기
하나의 타입 변수 T를 사용하는 제네릭 함수
필수 매개변수 initalValue의 타입은 T null
반환값의 타입 RefObject T
>
RefObject T
>
타입
레퍼런스 객체의 current 프로퍼티의 값 수정 불가
current 프로퍼티의 타입은 T null
다음과 같이 특정 HTML Element를 참조하는
불변 레퍼런스 객체를 만들어 사용할 때 좋다
RefObject T
>
setting.tsx
-
Dropdown 컴포넌트 수정
types/react 내부에 정의된 useRef 함수 타입
세번째 오버로드 시그니쳐 살펴보기
하나의 타입 변수 T를 사용하는 제네릭 함수
T의 기본값은 undefined 타입
매개변수가 없음
반환값의 타입 MutableRefObject T
>
첫번째 오버로드 시그니쳐와 유사하지만
레퍼런스 객체의 초기화 값을 나중에 설정하고 싶을때 용이
MutableRefObject T
>
components/Dropdown.tsx
setting.tsx
-
Dropdown 컴포넌트 수정
정리 : Dropdown 컴포넌트의 useRef 함수 타입 정의
inputRef는 특정 HTML Element를 참조할 레퍼런스 객체를
생성하는 함수
타입변수에 HTMLDivElement를 전달함
인수로 null을 전달함
components/Dropdown.tsx
setting.tsx
-
Dropdown 컴포넌트 수정
useEffect 내부의 타입 오류 수정하기
handleClickOutside 함수의 매개변수 e의 타입을
React.MouseEvent로 정의함
React.MouseEvent 는 리액트가 제공하는 합성 이벤트 객체
합성 이벤트 객체란?
• 크로스 브라우징 문제를 해결하기 위해 리액트가 제공하는 특별
한 이벤트 객체
• 브라우저 별로 상이한 형태의 이벤트 객체를 하나의 이벤트 객체
로 통합한 것
추가로 발생하는 오류 살펴보기
inputRef.current.contains 함수에서 오류 발생
addEvenetListener 함수에서 오류 발생
하나씩 천천히 해결해 봅시다 😃
components/Dropdown.tsx
setting.tsx
-
Dropdown 컴포넌트 수정
inputRef.current.contains 오류 해결하기
e.target의 타입은 EventTarget
contains 함수의 인수로 전달할 수 있는 타입은 Node
따라서 e.target을 HTMLElement 타입으로 단언하여 해결
HTMLElement 타입은 Node의 서브 타입임
setting.tsx
-
Dropdown 컴포넌트 수정
components/Dropdown.tsx
addEventListener 오류 해결하기
React.MouseEvent를 MouseEvent로 교체
합성 이벤트가 아닌 Native Event 타입으로 정의
Dropdown 컴포넌트 마이그레이션 완료 🎉
setting.tsx
pages/setting.tsx
다시 setting.tsx로 돌아와서
onChange 이벤트 핸들러 내부의 setTheme 오류 수정
setting.tsx 마이그레이션 완료 🎉
items/ id .tsx
pages/items/ id .tsx
id .js
->
id .tsx
일단 getServerSideProps 부터 살펴보기
1. context 파라미터 타입 정의 필요
2. /products API 모듈화 필요해 보임
3. /size reviews API 모듈화 필요해 보임
items/ id .tsx
pages/items/ id .tsx
context 파라미터 타입 정의하기
Next.js 내장 GetServerSidePropsContext 타입 이용
새로운 오류 발생
context.params가 undefined 일 수 있다는 오류 발생
GetServerSidePropsContext 타입의 params는 선택적 프로
퍼티이기 때문임
items/ id .tsx
pages/items/ id .tsx
NonNull 단언 ! 을 이용해 오류 해결
• context.params가 존재할 것이라고 단언
• 이후 string 타입으로 단언
items/ id .tsx
pages/items/ id .tsx
개별 상품을 불러오는 API 모듈화
lib/api.ts에 fetchProduct 함수 추가
lib/api.ts
분리
pages/items/ id .tsx
items/ id .tsx
개별 상품을 불러오는 API 모듈화
lib/api.ts에 fetchProduct 함수 추가
getServerSideProps에서 불러와 사용
lib/api.ts
items/ id .tsx
pages/items/ id .tsx
리뷰 불러오는 로직 분리 가능해보임
1. 분리하기 위해 먼저 API 데이터 타입 정의 필요
• SizeReview 아이템 타입 types.ts 파일에 정의
types.ts
items/ id .tsx
pages/items/ id .tsx
lib/api.ts
분리
리뷰 불러오는 로직 분리 가능해보임
2. 로직 분리
items/ id .tsx
pages/items/ id .tsx
리뷰 불러오는 로직 분리 가능해보임
2. 로직 분리
lib/api.ts
items/ id .tsx
pages/items/ id .tsx
Product 컴포넌트 Props 매개변수 타입 정의
-
InferGetServerSidePropsType T
>
사용
items/ id .tsx
pages/items/ id .tsx
컴포넌트 내부의 오류 수정
• handleSubmit 함수의 매개변수 타입
• React.FormEvent 타입으로 정의
• form 태그의 onSubmit 이벤트 핸들러이기 때문
items/ id .tsx
pages/items/ id .tsx
컴포넌트 내부의 오류 수정
• handleInputChange 함수의 매개변수 타입 정의
• React.ChangeEvent HTMLInputElement 타입 정의
• 타입 변수 미 설정시 name, value 추론 불가
• handleChange 함수의 매개변수 타입 정의
마이그레이션 완료 🎉
혹시 Button 컴포넌트에서 오류가 발생하면 as 프로퍼티를 없애주세요
app.tsx 수정
pages/ app.tsx
app.js
->
app.tsx로 수정
App 컴포넌트의 props 타입
Next.js 내장 타입 AppProps로 정의
404, document 수정
404.js
->
404.tsx
document.js
->
documents.tsx
별 다른 변경사항 없음
1. 프로젝트에 타입스크립트 세팅하기
• 타입스크립트 관련 라이브러리 설치하기
• 타입스크립트 컴파일러 옵션 설정하기
2. 페이지 단위로 타입스크립트 적용하기
• index 페이지
• search 페이지
• setting 페이지
• items/ id 페이지
• 그 외의 페이지들
3. 컴포넌트 단위로 타입스크립트 적용하기
• Button 컴포넌트
• ButtonLink 컴포넌트
• Container 컴포넌트
Button 컴포넌트
Button.js
->
Button.tsx
오류가 발생하지는 않음
• className에는 기본값이 존재함 string으로 자동 추론
• …props 는 인덱스 시그니쳐 key : string : any 타입으로 추론 됨
그러나 안전하지는 않음
• …props에 어떤 추가적인 프로퍼티가 들어올 지 모르는 상황
• button 태그에 전달되지 않아야 할 프로퍼티도 전달될 가능성 있음
components/Button.tsx
Button 컴포넌트
• props의 타입을
React.ComponentPropsWithoutRef button 으로 정의
• React.ComponentPropsWithoutRef button 타입?
• types/react에서 제공하는 기본 내장 타입
• T에 전달하는 Element의 모든 Props를 추출하는 타입
• 이렇게 사용하면 기존의 button Element에 전달할 수 있는 모든
Props를 사용 가능
• 대신 WithoutRef가 붙어있으므로 ref는 사용 불가
• 만약 ref를 사용하고 싶다면 ComponentPropsWithRef T
>
사용
components/Button.tsx
Button 컴포넌트
만약 추가적인 프로퍼티가 필요하다면?
• interface로 Props 타입을 별도로 선언함
• React.ComponentProps button 을 확장하게 함
• 기존 button에 전달할 수 있는 모든 Props를 갖게 됨
• 추가적인 프로퍼티는 interface 내부에 작성
components/Button.tsx
Button 컴포넌트
그러나 만약 추가한 프로퍼티가 중복된 이름을 가질 경우 오류 발생
• Props 인터페이스에 type 프로퍼티를 추가 오류 발생
• type은 이미 React.ComponentProps button 타입에 정의됨
• 타입스크립트는 이를 동일한 프로퍼티의 타입을 재 정의하는 것으로 해석
• 확장된 인터페이스에서 프로퍼티의 타입을 재 정의할 때에는
슈퍼 타입에 정의된 타입의 서브 타입으로만 정의할 수 있음
components/Button.tsx
Button 컴포넌트
Omit T, K
>
유틸리티 타입을 이용
• Omit T, K
>
는 T 타입으로 부터 K에 해당하는 프로퍼티를 제외하는 타입
• Omit React.ComponentProps button , type 은
React.ComponentProps button 으로부터 type 프로퍼티를 제외
하는 타입을 반환함
• type 프로퍼티를 제외하고 확장하기 때문에 오류가 발생하지 않음
components/Button.tsx
Button 컴포넌트
추가해야 하는 프로퍼티가 많고 다양하다면?
• Props 인터페이스는 아무것도 확장하지 않도록 변경
• Button 컴포넌트의 props의 타입으로 Props Omit … 타입 정의
• Omit React.ComponentProps button , keyof Props 타입?
• React.ComponentProps button 으로부터
Props 타입에 존재하는 프로퍼티들을 제외한 타입을 추출
components/Button.tsx
ButtonLink 컴포넌트
ButtonLink.js
->
ButtonLink.tsx
• Props 타입을 인터페이스로 선언
• Next.js 내장 타입인 LinkProps 타입을 확장하도록 설정
• LinkProps 타입은 Link 컴포넌트에 전달할 수 있는 Props들
이 선언되어 있는 타입
components/ButtonLink.tsx
Container 컴포넌트
Container.js
->
Container.tsx
• Props 타입을 인터페이스로 선언
• children 타입을 React.ReactNode 내장 타입으로 정의
• ReactNode는 React의 children으로 사용될 수 있는 거의 모
든 타입을 포함하는 범용적인 타입임
components/Container.tsx
끝

More Related Content

Similar to 코드잇-타스-특강.pdf

Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본ssuser0c2478
 
WzDat과 Pandas를 통한 로그 데이터 분석
WzDat과 Pandas를 통한 로그 데이터 분석WzDat과 Pandas를 통한 로그 데이터 분석
WzDat과 Pandas를 통한 로그 데이터 분석정주 김
 
Custom Xcode Template (with VIPER)
Custom Xcode Template (with VIPER)Custom Xcode Template (with VIPER)
Custom Xcode Template (with VIPER)Bongwon Lee
 
Microsoft pp lpdf
Microsoft pp lpdfMicrosoft pp lpdf
Microsoft pp lpdfHYUNWOO KIM
 
NDC 2015 마비노기 듀얼 패치 시스템
NDC 2015 마비노기 듀얼 패치 시스템NDC 2015 마비노기 듀얼 패치 시스템
NDC 2015 마비노기 듀얼 패치 시스템tcaesvk
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7Chris Ohk
 
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연Joohyun Han
 
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기Ted Won
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 pptInjae Lee
 
A tour of C++ : the basics
A tour of C++ : the basicsA tour of C++ : the basics
A tour of C++ : the basicsJaewon Choi
 
The beginner’s guide to 웹 크롤링 (스크래핑)
The beginner’s guide to 웹 크롤링 (스크래핑)The beginner’s guide to 웹 크롤링 (스크래핑)
The beginner’s guide to 웹 크롤링 (스크래핑)Eunjeong (Lucy) Park
 
이클립스 플랫폼
이클립스 플랫폼이클립스 플랫폼
이클립스 플랫폼Kenu, GwangNam Heo
 
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기CONNECT FOUNDATION
 
Git 기본개념과 사용법 그리고 어플리케이션
Git 기본개념과 사용법 그리고 어플리케이션Git 기본개념과 사용법 그리고 어플리케이션
Git 기본개념과 사용법 그리고 어플리케이션Dabi Ahn
 
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기Joongi Kim
 
김찬웅_그룹웨어에 새 에너지를_NDC15
김찬웅_그룹웨어에 새 에너지를_NDC15김찬웅_그룹웨어에 새 에너지를_NDC15
김찬웅_그룹웨어에 새 에너지를_NDC15Chanwoong Kim
 

Similar to 코드잇-타스-특강.pdf (20)

Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
WzDat과 Pandas를 통한 로그 데이터 분석
WzDat과 Pandas를 통한 로그 데이터 분석WzDat과 Pandas를 통한 로그 데이터 분석
WzDat과 Pandas를 통한 로그 데이터 분석
 
Custom Xcode Template (with VIPER)
Custom Xcode Template (with VIPER)Custom Xcode Template (with VIPER)
Custom Xcode Template (with VIPER)
 
Microsoft pp lpdf
Microsoft pp lpdfMicrosoft pp lpdf
Microsoft pp lpdf
 
NDC 2015 마비노기 듀얼 패치 시스템
NDC 2015 마비노기 듀얼 패치 시스템NDC 2015 마비노기 듀얼 패치 시스템
NDC 2015 마비노기 듀얼 패치 시스템
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7
 
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연
200725 AWS 클라우드 컴퓨팅으로 배우는 생물정보학 - 덕성여대 강연
 
Exp manager
Exp managerExp manager
Exp manager
 
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기
JCO 11th 클라우드 환경에서 Java EE 운영 환경 구축하기
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 ppt
 
Git
Git Git
Git
 
Html5
Html5 Html5
Html5
 
A tour of C++ : the basics
A tour of C++ : the basicsA tour of C++ : the basics
A tour of C++ : the basics
 
The beginner’s guide to 웹 크롤링 (스크래핑)
The beginner’s guide to 웹 크롤링 (스크래핑)The beginner’s guide to 웹 크롤링 (스크래핑)
The beginner’s guide to 웹 크롤링 (스크래핑)
 
이클립스 플랫폼
이클립스 플랫폼이클립스 플랫폼
이클립스 플랫폼
 
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기
[부스트캠프 Tech Talk] 최재필_P 스테이지에서 Git으로 협업하기
 
Git 기본개념과 사용법 그리고 어플리케이션
Git 기본개념과 사용법 그리고 어플리케이션Git 기본개념과 사용법 그리고 어플리케이션
Git 기본개념과 사용법 그리고 어플리케이션
 
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기
Python Korea 2014년 6월 세미나 - Windows 환경에서 Python 개발환경 세팅하기
 
김찬웅_그룹웨어에 새 에너지를_NDC15
김찬웅_그룹웨어에 새 에너지를_NDC15김찬웅_그룹웨어에 새 에너지를_NDC15
김찬웅_그룹웨어에 새 에너지를_NDC15
 
12books
12books12books
12books
 

코드잇-타스-특강.pdf

  • 2. 목차 1. 프로젝트에 타입스크립트 세팅하기 • 타입스크립트 관련 라이브러리 설치하기 • 타입스크립트 컴파일러 옵션 설정하기 2. 페이지 단위로 타입스크립트 적용하기 • index 페이지 • search 페이지 • setting 페이지 • items/ id 페이지 • 그 외의 페이지들 3. 컴포넌트 단위로 타입스크립트 적용하기 • Button 컴포넌트 • ButtonLink 컴포넌트 • Container 컴포넌트
  • 3. 1. 프로젝트에 타입스크립트 세팅하기 • 타입스크립트 관련 라이브러리 설치하기 • 타입스크립트 컴파일러 옵션 설정하기 2. 페이지 단위로 타입스크립트 적용하기 • index 페이지 • search 페이지 • setting 페이지 • items/ id 페이지 • 그 외의 페이지들 3. 컴포넌트 단위로 타입스크립트 적용하기 • Button 컴포넌트 • ButtonLink 컴포넌트 • Container 컴포넌트
  • 4. 패키지에 타입스크립트 관련 라이브러리 추가하기 npm i save dev typescript types/react types/node 설치하는 라이브러리 별 의미는 다음과 같습니다. • typescript : 타입스크립트 라이브러리 tsc를 포함하고 있음 • types/react : react 내장 기능들의 타입 정보를 가지고 있는 라이브러리 • types/node : node 내장 기능들의 타입 정보를 가지고 있는 라이브러리
  • 5. 패키지에 타입스크립트 관련 라이브러리 추가하기 npm i save dev typescript types/react types/node types/next는 왜 설치하지 않나요? • types/* 패키지들은 JS로 작성된 라이브러리들의 타입 정보만을 담고있는 패키지임 Definitely Typed • nextjs 또한 자바스크립트로 만들어졌기에 이전에는 types/next가 존재했음 • 그러나 현재에는 nextjs에 타입 선언 파일이 자체적으로 포함되므로 따로 설치할 필요가 없음
  • 6. 패키지에 타입스크립트 관련 라이브러리 추가하기 npm i save dev typescript types/react types/node save dev 옵션을 사용하는 이유 • 모든 타입스크립트의 타입 관련 코드는 컴파일 이후 사라지게 됨 • 따라서 프로덕션 상황에서는 타입 관련 라이브러리가 필요하지 않음 • 이에 개발 모드에만 사용하는 라이브러리로 설치하기 위해 save dev 옵션을 사용함 타이핑 하기 귀찮다면 - D 로도 사용할 수 있음
  • 7. 타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기 이미 존재하는 Next.js 프로젝트에 타입스크립트 컴파일러 옵션 설정하기 • 타입스크립트 컴파일러 옵션은 tsconfig.json에 설정함 • 따라서 프로젝트 루트 아래에 tsconfig.json 파일을 생성하고 JSON Format으로 필요한 옵션들을 직접 설정해줘야 함 • 그러나 Next.js 프로젝트를 위해 설정해줘야 할 옵션 들이 너무 많음 매번 프로젝트마다 일일이 설정하기 귀찮음 • 이럴때에는 Next.js에게 타입스크립트를 사용할거라고 알려줘서 자동으로 생성하게 만들 수 있음 자동으로 타입스크립트 컴파일러 옵션 설정하는 방법 1. 최소 하나 이상의 파일이 타입스크립트 확장자 TS, TSX 를 갖도록 파일 생성 또는 변경하기 2. npm run dev 명령을 입력하여 프로젝트를 그냥 실행하기 3. 자동으로 tsconfig.json 파일 생성
  • 8. 타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기 1. 최소 하나 이상의 파일이 타입스크립트 확장자 TS, TSX 를 갖도록 파일 생성 또는 변경하기 • pages/index.js -> pages/index.tsx로 변경함 • 확장자 변경시 발생하는 오류는 일단 무시해도 됨
  • 9. 타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기 2. npm run dev 명령을 입력하여 프로젝트를 그냥 실행하기 • 오류는 무시하고 터미널에 npm run dev을 명령하여 개발 모드로 프로젝트 실행 • We detected TypeScript in your project and create a tsconfig.json file for you 라는 메세지가 출력됨 • 해석 : 타입스크립트 파일을 너의 프로젝트에서 찾았어 tsconfig.json을 자동으로 만들어줄게 라는 뜻
  • 10. 타입스크립트 컴파일러 옵션 설정하기 tsconfig.json 생성하기 3. 자동 생성된 tsconfig.json과 next env.d.ts을 확인하기 • 프로젝트 루트에 다음 파일들이 자동 생성 됨 • next env.d.ts • tsconfig.json
  • 11. 자동 설정된 컴파일러 옵션 살펴보기 tsconfig.json 파일에 설정된 옵션 살펴보기 • 상당히 많은 개수의 옵션이 자동으로 설정되어 있다. • 이미 강의에서 다룬 옵션 30 처음 보는 옵션 70 으로 이루어짐 • 이런 옵션들을 모른다고 어디서 잡아가지는 않는다. • 그러나 우리가 자주 사용하는 도구 React, Next 에서 주로 사용 되는 옵션들이므로 알아두면 꽤 도움이 된다.
  • 12. 자동 설정된 컴파일러 옵션 살펴보기 1/13 lib 옵션 • Library 라는 의미 • 타입스크립트의 컴파일 과정에서 사용될 라이브러리들을 설정하는 옵션 • 배열 형태로 사용할 라이브러리의 이름을 설정 • 각각의 라이브러리는 이름에 맞는 내장 API 들의 타입을 정의함 • dom : DOM 관련 타입이 정의되어 있음 • ex window, document, etc • dom.iterable : 반복 가능한 DOM 요소의 타입들이 정의되어 있음 • ex HTMLCollection, NodeList, CSSRuleList, etc • esnext : 최신 ecma 스크립트에서 제공하는 자바스크립트 내장 API들에 대한 타입이 정의되어 있음 • ex Promise, Arrow Functions, etc • * 결론적으로 이 타입스크립트 프로젝트를 컴파일 할 때 dom, dom.iterable, esnext 관련 타입 정보가 필요하다고 설정해 둔 것
  • 13. 자동 설정된 컴파일러 옵션 살펴보기 2/13 allowJS 옵션 • 이미 강의에서 한 번 다룬 적이 있는 옵션 • 타입스크립트 파일 ts, tsx 에서 자바스크립트 파일 js, jsx 를 불러와 사용할 수 있도록 허용하는 옵션 • 이 옵션을 키면 a.ts에서 b.js를 불러 사용가능 • 처음부터 타입스크립트로 프로젝트를 개발하는 경우에는 필요하지 않을 수 있음 • 자바스크립트 파일을 생성하지 않을 것이기 때문에 • 그러나 자바스크립트를 마이그레이션 할 때 매우 유용한 옵션 • 모든 자바스크립트 파일을 한번에 타입스크립트 파일로 바꾸기 어렵기 때문 • 순서대로 하나씩 변경할 때 아주 유용한 옵션
  • 14. 자동 설정된 컴파일러 옵션 살펴보기 3/13 skipLibCheck 옵션 • 선언 파일들의 타입 체킹을 건너뛰는 옵션 • 선언 파일이란? *.d.ts 확장자를 갖는 파일들을 말함 • 이 옵션을 허용하는 이유 컴파일 시간을 줄이기 위해 • 엄밀히 말하자면 타입스크립트 컴파일 타임을 줄이기 위함 • 대다수의 라이브러리들은 d.ts 파일을 통해 타입 정보를 제공함 • 따라서 모든 라이브러리들의 타입 정보를 일일이 검사하면 오래 걸림
  • 15. 자동 설정된 컴파일러 옵션 살펴보기 4/13 strict 옵션 • 엄격한 타입 검사 모드를 설정하는 옵션 • 이 옵션을 키면 아래의 옵션 들도 함께 켜짐 • noImplicitAny : 암시적 any 비 허용 • strictNullChecks : null 타입이 아닌 변수에 null 할당 비 허용 • etc … • Next.js는 기본적으로 이 옵션을 비활성화 false 로 설정함 • 마이그레이션 과정에서 최대한 유연하게 작동하도록 자동 설정 됨 • 향후 우리가 직접 마이그레이션 할 때에는 활성화 true 할 예정
  • 16. 자동 설정된 컴파일러 옵션 살펴보기 5/13 forceConsistentCasingInFileNames 옵션 • 파일 이름에 일관된 대 소문자를 강제하는 옵션 • 파일 이름에 대소문자를 구별하도록 설정하는 옵션임 ex a.ts <-> A.ts를 다르게 평가하도록 설정하는 옵션 • 굳이 구별하지 않을 이유가 없음
  • 17. 자동 설정된 컴파일러 옵션 살펴보기 6/13 noEmit 옵션 • 컴파일시 자바스크립트 파일을 생성하지 않도록 설정하는 옵션 • 이 옵션이 활성화 되면 TSC는 타입 체킹만 진행하고 트랜스파일 된 자바스 크립트 코드를 생성하지 않도록 제한 됨 • 이 옵션을 사용하는 이유 • Next.js, Raect.js 프로젝트에서는 Webpack, Vite, Turbopack 등의 번 들러를 이용함 • 이 경우 Babel이나 SWC등의 별도의 트랜스파일러를 이용해 컴파일을 진 행하게 됨 • 타입스크립트를 컴파일하고 나서 별도의 번들링 작업을 추가로 진행하기 때 문에 별도의 자바스크립트 파일을 생성할 필요가 없음
  • 18. 자동 설정된 컴파일러 옵션 살펴보기 7/13 incremental 옵션 • 증분 컴파일 지원할 것인지 결정하는 옵션 • 증분이란 수학적인 용어로 변화한 양을 나타내는 말 • ex 증분 백업 : 변화한 데이터만 별도로 추가 백업하는 방법 • 증분 컴파일이란 • 컴파일 기록을 계속해서 남겨둠으로써 특정 파일에 변화가 발생해 다시 컴 파일 해야 하는 경우 이전의 기록을 토대로 변화한 파일만 다시 컴파일 하 는 방법 • 쉽게 말해 변화한 TS 파일만 다시 컴파일 하게 됨 빠른 컴파일 시간 확보를 위함
  • 19. 자동 설정된 컴파일러 옵션 살펴보기 8/13 esModuleInterop 옵션 • CJS 방식으로 내보낸 값을 ES 방식의 Import로 가져올 수 있도록 해주는 옵션 • CJS로 작성된 모듈로부터 default import를 이용할 수 있음 • ex • React는 default로 내보낸 값이 없으나 esModuleInterop 설정을 켜주면 import React from react 같은 방식으로 default 값을 가져올 수 있다.
  • 20. 자동 설정된 컴파일러 옵션 살펴보기 9/13 module 옵션 • 컴파일 된 자바스크립트 코드가 사용할 모듈의 버전을 설정하는 옵션
  • 21. 자동 설정된 컴파일러 옵션 살펴보기 10/13 moduleResolution 옵션 • 타입스크립트의 모듈 해석 방식을 결정하는 옵션 • 모듈 해석이란? • import A from B 일때 B의 위치를 찾는 방식을 의미함 • 타입스크립트는 다음 2가지 모듈 해석 방식을 제공 • Classic 기본값 • Node 권장값 • Classic 방식의 동작 • 절대 경로일 때 프로젝트의 루트에서 모듈을 찾음 • Node 방식의 동작 • 절대 경로일 때 node modules 폴더 아래에서 모듈을 찾음 • 예외적으로 baseURL 또는 paths 설정시 매핑된 경로에서 모듈을 찾음
  • 22. 자동 설정된 컴파일러 옵션 살펴보기 11/13 resolveJsonModule 옵션 • 타입스크립트에서 JSON 파일을 불러오도록 허용하는 옵션 • 불러온 JSON의 형태에 맞게 타입을 자동 추론해주기도 함
  • 23. 자동 설정된 컴파일러 옵션 살펴보기 12/13 isolatedModules 옵션 • 모든 타입스크립트 파일이 독립적인 모듈로 동작하는 것 처럼 컴파일 하는 옵션 • Babel, SWC 등의 TSC가 아닌 컴파일러는 타입스크립트 파일을 파일 별 로 하나 하나 변환하는데 이때 오류가 발생할 수 있는 상황들에 대해 경고 • TS 5.0 이하까지는 모든 파일이 개별 모듈로 취급 되길 강제했으나 이제 그 렇지는 않음
  • 24. 자동 설정된 컴파일러 옵션 살펴보기 13/13 jsx 옵션 • 타입스크립트에서 JSX를 사용하기 위해 설정하는 옵션
  • 25. Path Alias 설정하기 타입스크립트 환경에서 Path Alias를 적용하기 위해 jsconfig.json 파일에 설정되어 있던 paths 옵션을 tsconfig.json 파일에 그대로 붙여넣기
  • 26. Strict 모드 켜기 엄격한 타입 검사를 통해 마이그레이션 과정에서 잠재적인 타입오류들을 다 찾아내기 위해 strict 옵션 true로 설정
  • 27. 1. 프로젝트에 타입스크립트 세팅하기 • 타입스크립트 관련 라이브러리 설치하기 • 타입스크립트 컴파일러 옵션 설정하기 2. 페이지 단위로 타입스크립트 적용하기 • index 페이지 • search 페이지 • setting 페이지 • items/ id 페이지 • 그 외의 페이지들 3. 컴포넌트 단위로 타입스크립트 적용하기 • Button 컴포넌트 • ButtonLink 컴포넌트 • Container 컴포넌트
  • 28. index.tsx index.tsx 파일에는 index 페이지의 로직이 정의되어 있음
  • 29. index.tsx index.js -> index.tsx 먼저 Home 컴포넌트의 Props 타입 정의가 필요함 props가 암시적 any로 추론되고 있음 props로 부터 구조 분해 할당한 products 또한 any 타입으로 추론 되므로 안전하지 않은 상태 따라서 Products의 타입을 먼저 정의한 다음 Props 타입을 정의 해주어야 함 pages/index.tsx
  • 30. index.tsx Product 타입 정의하기 이 타입은 다른 파일에서도 사용할 것으로 예상되므로 types.ts 파일을 만들어 해당 파일 내에 모듈화 /types.ts 새롭게 생성
  • 31. index.tsx pages/index.tsx로 돌아와서 1. import 문으로 방금 만든 Product 타입을 불러옴 2. Props 타입을 정의 3. getStaticProps의 반환값 타입을 정의 • Home 컴포넌트가 제공받는 매개변수 props의 값이 이 함수의 리턴값이기 때문 4. Home 컴포넌트의 Props 매개변수 타입 정의 pages/index.tsx
  • 32. index.tsx 🚨 그러나 이렇게 작성하면 타입으로 인해 추가되는 코드의 양이 꽤 많음 이럴 때 Next.js에서 기본 제공하는 유틸리티 타입인 inferGetStaticPropsType T > 을 이용하면 좀 더 코드를 클린하게 리팩토링 할 수 있음 pages/index.tsx
  • 33. index.tsx pages/index.tsx 좀 더 클린하게 만들어보기 🧹 inferGetStaticPropsType T > 타입 변수 T에 getStaticProps 함수의 타입을 전달하면 해당 getStaticProps 함수의 props의 타입을 추출하는 Next.js 내장 유틸리티 타입
  • 34. index.tsx pages/index.tsx 그런데 이렇게 해주면 추가적인 문제가 생김 🚨 props의 타입이 products를 포함한 객체타입이라는 것 까지는 추론되나, products의 타입이 any로 추론됨 axios.get으로 불러오는 res의 타입이 any이므로 res.data.results에 해당하는 products도 any가 되기 때문
  • 35. index.tsx pages/index.tsx 따라서 axios.get의 타입을 정의해줘야 함 axios.get 메서드는 제네릭 함수이므로 호출 시 타입변수 T에 제공한 타입이 곧 반환값의 타입이 됨 그 결과 props의 타입도 잘 추론 됨
  • 36. index.tsx lib/api.ts 새로 생성 여기서 추가로 더 클린하게! getStaticProps 내부의 API 로직을 별도의 파일로 분리 • lib/api.ts 파일을 생성 • 해당 파일 아래에 fetchProducts 함수로 작성 분리
  • 37. index.tsx pages/index.tsx 여기서 추가로 더 클린하게! getStaticProps 내부의 API 로직을 별도의 파일로 분리 • lib/api.ts 파일을 생성 • 해당 파일 아래에 fetchProducts 함수로 작성 • 불러다 사용 index.tsx 리팩토링 완성 🎉
  • 38. search.tsx search.tsx 에는 /search 페이지의 로직이 정의되어 있음
  • 39. search.tsx search.js -> search.tsx로 파일명 변경 오류가 발생하는 부분 살펴보기 1. getServerSideProps • context 매개변수가 암시적 any 타입으로 추론되고 있음 2. Search 컴포넌트 • props가 암시적 any 타입으로 추론되고 있음 하나씩 천천히 수정해보도록 하겠습니다 pages/search.tsx
  • 40. search.tsx getServerSideProps 함수의 오류부터 해결 • context 매개변수의 타입을 GetServerSidePropsContext로 정의 pages/search.tsx node modules/next/types/index.d.ts
  • 41. search.tsx getServerSideProps 내부 타입 정의 • context.query q 는 string string undefined 타입으로 추론 • ?q 검색어 : string 타입 • ?q 검색어1 q 검색어2 : string 타입 • q가 없을 경우 : undefined 타입 • stringifiedQuery 변수를 선언해 string 타입으로 좁혀줌 • axios.get 반환값 타입 설정 pages/search.tsx
  • 42. search.tsx getServerSideProps에서 비동기 로직 분리 이전에 lib/api.ts에 만들어둔 fetchProducts를 수정하여 함께 사용 pages/search.tsx lib/api.ts 분리
  • 43. search.tsx getServerSideProps에서 비동기 로직 분리 이전에 lib/api.ts에 만들어둔 fetchProducts를 수정하여 함께 사용 pages/search.tsx lib/api.ts
  • 44. search.tsx Search 컴포넌트의 Props 타입 정의 • InferGetServerSidePropsType T > 타입 으로 정의 • InferGetStaticPropsType T > 와 유사한 타입 search.tsx 마이그레이션 완료 🎉 pages/search.tsx
  • 46. setting.tsx setting.js -> setting.tsx로 확장자 변경 이 페이지에서 사용하는 컴포넌트 Dropdown ThemeContext 컴포넌트들 부터 마이그레이션 하는 방향이 나을 것 같다 pages/setting.tsx
  • 47. setting.tsx - ThemeContext 수정 ThemeContext.js -> ThemeContext.tsx 로 수정 오류가 발생하고 있는 부분 • 8번 : createContext 함수 호출 • 10번: ThemeProvider 컴포넌트의 props 쉬운 부분, 간단한 부분부터 수정하는 순서로 진행 lib/ThemeContext.tsx
  • 48. setting.tsx - ThemeContext 수정 ThemeProvider 컴포넌트 Props 타입 정의 • ThemeProvider 컴포넌트의 Props 타입 설정 • children 프로퍼티는 ReactNode 타입으로 정의 • ReactNode 타입 • React에서 Node로 분류될 수 있는 모든 타입의 유니언 lib/ThemeContext.tsx
  • 49. setting.tsx - ThemeContext 수정 useState 타입 정의 • theme State는 dark 아니면 light 의 값을 가짐 • useState는 타입 변수가 없으면 초기값을 기준으로 타입을 추론 • theme State의 타입이 기본적으로는 string 타입으로 추론 • 더 정밀한 타입 정의를 위해 Theme 타입을 types.ts에 선언한 다음 useState의 타입 변수로 제공 lib/ThemeContext.tsx types.ts
  • 50. setting.tsx - ThemeContext 수정 createContext 타입 정의 오류 원인부터 살펴보기 • createContext 메서드를 호출할 때 오류가 발생함 createContext 메서드의 타입 살펴보기 • 타입변수 T를 제공받는 제네릭 함수 • 하나의 필수 매개변수 defaultValue를 제공받음 • 반환값의 타입은 Context T > 오류 원인 • 필수 매개 변수에 값이 제공되지 않았기 때문 lib/ThemeContext.tsx types/react 내부에 정의된 createContext T >
  • 51. setting.tsx - ThemeContext 수정 createContext 타입 정의 타입 정의하기 • theme와 setTheme를 포함한 객체와 null 타입의 유니온 타입 으로 정의함 • theme State의 타입은 Theme로 정의함 • setTheme의 타입은 Dispatch SetStateAction Theme 로 정의함 • Dispatch SetStateAction T > > 는 리액트 내장 타입 • theme : Theme => void 형태로 정의해도 되지만 함수 형 업데이트 등의 다양한 인터페이스를 제공하기 위해 좀 더 공식적인 방식을 사용함 lib/ThemeContext.tsx
  • 52. setting.tsx - ThemeContext 수정 ThemeContext 마이그레이션 완료 🎉 • 타 컴포넌트에서 불러 사용할 useTheme 의 타입이 잘 추론되 는 걸 확인할 수 있음 lib/ThemeContext.tsx
  • 53. setting.tsx - ThemeContext 수정 setting.tsx로 돌아와 useTheme의 타입이 잘 추론되는지 확인 • theme : Theme 타입으로 추론 ✅ • setTheme : Dispatch SetStateAction Theme 로 추론 ✅ pages/setting.tsx
  • 54. setting.tsx - Dropdown 컴포넌트 수정 Dropdown.js -> Dropdown.tsx로 확장자 변경 다양한 곳에서 오류 발생 차례대로 하나 하나 해결해봅시다 😃 components/Dropdown.tsx
  • 55. setting.tsx - Dropdown 컴포넌트 수정 components/Dropdown.tsx pages/setting.tsx Dropdown 컴포넌트의 Props 타입 정의 - Setting 컴포넌트에서 전달하는 Props를 기준으로 정의함
  • 56. setting.tsx - Dropdown 컴포넌트 수정 components/Dropdown.tsx Dropdown 컴포넌트의 useRef 함수 타입 정의 타입 변수로 HTMLDivElement 설정 이 레퍼런스 객체가 참조할 태그가 div 이기 때문 useRef 메서드의 자세한 타입 정보는 뒷 슬라이드에!
  • 57. setting.tsx - Dropdown 컴포넌트 수정 types/react 내부에 정의된 useRef 함수 타입 React의 useRef의 타입 살펴보기 • 함수 오버로딩이 구현되어 있음 • 동일한 함수에 여러 버전의 타입을 정의해 매개변수의 개수나 타입에 따라 각각 다른 버전의 함수 타입을 사용하게 하는 문법 • 3개의 오버로드 시그니쳐가 존재함 • 3가지 버전으로 사용할 수 있다는 의미 • 타입 변수나 인수로 무엇을 전달하느냐에 따라서 반환하는 RefObject의 타입이 달라짐 이 차이점을 알면 컴포넌트 내부에서 변수로 사용하기 위한 레퍼런스 객체와 DOM Element를 참조하기 위해 사용하는 레퍼런스 객체를 나눠 사용할 수 있게 됨
  • 58. setting.tsx - Dropdown 컴포넌트 수정 types/react 내부에 정의된 useRef 함수 타입 첫번째 오버로드 시그니쳐 살펴보기 하나의 타입 변수 T를 사용하는 제네릭 함수 필수 매개변수 initalValue의 타입은 T 반환값의 타입 MutableRefObject T > MutableRefObjecT < T > 타입 레퍼런스 객체의 current 프로퍼티의 값 수정 가능 current 프로퍼티의 타입은 T 다음과 같이 컴포넌트 내부에서 변수의 역할을 수행할 레퍼런스 객체를 만들때 사용하면 좋다 MutableRefObject T >
  • 59. setting.tsx - Dropdown 컴포넌트 수정 types/react 내부에 정의된 useRef 함수 타입 두번째 오버로드 시그니쳐 살펴보기 하나의 타입 변수 T를 사용하는 제네릭 함수 필수 매개변수 initalValue의 타입은 T null 반환값의 타입 RefObject T > RefObject T > 타입 레퍼런스 객체의 current 프로퍼티의 값 수정 불가 current 프로퍼티의 타입은 T null 다음과 같이 특정 HTML Element를 참조하는 불변 레퍼런스 객체를 만들어 사용할 때 좋다 RefObject T >
  • 60. setting.tsx - Dropdown 컴포넌트 수정 types/react 내부에 정의된 useRef 함수 타입 세번째 오버로드 시그니쳐 살펴보기 하나의 타입 변수 T를 사용하는 제네릭 함수 T의 기본값은 undefined 타입 매개변수가 없음 반환값의 타입 MutableRefObject T > 첫번째 오버로드 시그니쳐와 유사하지만 레퍼런스 객체의 초기화 값을 나중에 설정하고 싶을때 용이 MutableRefObject T >
  • 61. components/Dropdown.tsx setting.tsx - Dropdown 컴포넌트 수정 정리 : Dropdown 컴포넌트의 useRef 함수 타입 정의 inputRef는 특정 HTML Element를 참조할 레퍼런스 객체를 생성하는 함수 타입변수에 HTMLDivElement를 전달함 인수로 null을 전달함
  • 62. components/Dropdown.tsx setting.tsx - Dropdown 컴포넌트 수정 useEffect 내부의 타입 오류 수정하기 handleClickOutside 함수의 매개변수 e의 타입을 React.MouseEvent로 정의함 React.MouseEvent 는 리액트가 제공하는 합성 이벤트 객체 합성 이벤트 객체란? • 크로스 브라우징 문제를 해결하기 위해 리액트가 제공하는 특별 한 이벤트 객체 • 브라우저 별로 상이한 형태의 이벤트 객체를 하나의 이벤트 객체 로 통합한 것 추가로 발생하는 오류 살펴보기 inputRef.current.contains 함수에서 오류 발생 addEvenetListener 함수에서 오류 발생 하나씩 천천히 해결해 봅시다 😃
  • 63. components/Dropdown.tsx setting.tsx - Dropdown 컴포넌트 수정 inputRef.current.contains 오류 해결하기 e.target의 타입은 EventTarget contains 함수의 인수로 전달할 수 있는 타입은 Node 따라서 e.target을 HTMLElement 타입으로 단언하여 해결 HTMLElement 타입은 Node의 서브 타입임
  • 64. setting.tsx - Dropdown 컴포넌트 수정 components/Dropdown.tsx addEventListener 오류 해결하기 React.MouseEvent를 MouseEvent로 교체 합성 이벤트가 아닌 Native Event 타입으로 정의 Dropdown 컴포넌트 마이그레이션 완료 🎉
  • 65. setting.tsx pages/setting.tsx 다시 setting.tsx로 돌아와서 onChange 이벤트 핸들러 내부의 setTheme 오류 수정 setting.tsx 마이그레이션 완료 🎉
  • 66. items/ id .tsx pages/items/ id .tsx id .js -> id .tsx 일단 getServerSideProps 부터 살펴보기 1. context 파라미터 타입 정의 필요 2. /products API 모듈화 필요해 보임 3. /size reviews API 모듈화 필요해 보임
  • 67. items/ id .tsx pages/items/ id .tsx context 파라미터 타입 정의하기 Next.js 내장 GetServerSidePropsContext 타입 이용 새로운 오류 발생 context.params가 undefined 일 수 있다는 오류 발생 GetServerSidePropsContext 타입의 params는 선택적 프로 퍼티이기 때문임
  • 68. items/ id .tsx pages/items/ id .tsx NonNull 단언 ! 을 이용해 오류 해결 • context.params가 존재할 것이라고 단언 • 이후 string 타입으로 단언
  • 69. items/ id .tsx pages/items/ id .tsx 개별 상품을 불러오는 API 모듈화 lib/api.ts에 fetchProduct 함수 추가 lib/api.ts 분리
  • 70. pages/items/ id .tsx items/ id .tsx 개별 상품을 불러오는 API 모듈화 lib/api.ts에 fetchProduct 함수 추가 getServerSideProps에서 불러와 사용 lib/api.ts
  • 71. items/ id .tsx pages/items/ id .tsx 리뷰 불러오는 로직 분리 가능해보임 1. 분리하기 위해 먼저 API 데이터 타입 정의 필요 • SizeReview 아이템 타입 types.ts 파일에 정의 types.ts
  • 72. items/ id .tsx pages/items/ id .tsx lib/api.ts 분리 리뷰 불러오는 로직 분리 가능해보임 2. 로직 분리
  • 73. items/ id .tsx pages/items/ id .tsx 리뷰 불러오는 로직 분리 가능해보임 2. 로직 분리 lib/api.ts
  • 74. items/ id .tsx pages/items/ id .tsx Product 컴포넌트 Props 매개변수 타입 정의 - InferGetServerSidePropsType T > 사용
  • 75. items/ id .tsx pages/items/ id .tsx 컴포넌트 내부의 오류 수정 • handleSubmit 함수의 매개변수 타입 • React.FormEvent 타입으로 정의 • form 태그의 onSubmit 이벤트 핸들러이기 때문
  • 76. items/ id .tsx pages/items/ id .tsx 컴포넌트 내부의 오류 수정 • handleInputChange 함수의 매개변수 타입 정의 • React.ChangeEvent HTMLInputElement 타입 정의 • 타입 변수 미 설정시 name, value 추론 불가 • handleChange 함수의 매개변수 타입 정의 마이그레이션 완료 🎉 혹시 Button 컴포넌트에서 오류가 발생하면 as 프로퍼티를 없애주세요
  • 77. app.tsx 수정 pages/ app.tsx app.js -> app.tsx로 수정 App 컴포넌트의 props 타입 Next.js 내장 타입 AppProps로 정의
  • 79. 1. 프로젝트에 타입스크립트 세팅하기 • 타입스크립트 관련 라이브러리 설치하기 • 타입스크립트 컴파일러 옵션 설정하기 2. 페이지 단위로 타입스크립트 적용하기 • index 페이지 • search 페이지 • setting 페이지 • items/ id 페이지 • 그 외의 페이지들 3. 컴포넌트 단위로 타입스크립트 적용하기 • Button 컴포넌트 • ButtonLink 컴포넌트 • Container 컴포넌트
  • 80. Button 컴포넌트 Button.js -> Button.tsx 오류가 발생하지는 않음 • className에는 기본값이 존재함 string으로 자동 추론 • …props 는 인덱스 시그니쳐 key : string : any 타입으로 추론 됨 그러나 안전하지는 않음 • …props에 어떤 추가적인 프로퍼티가 들어올 지 모르는 상황 • button 태그에 전달되지 않아야 할 프로퍼티도 전달될 가능성 있음 components/Button.tsx
  • 81. Button 컴포넌트 • props의 타입을 React.ComponentPropsWithoutRef button 으로 정의 • React.ComponentPropsWithoutRef button 타입? • types/react에서 제공하는 기본 내장 타입 • T에 전달하는 Element의 모든 Props를 추출하는 타입 • 이렇게 사용하면 기존의 button Element에 전달할 수 있는 모든 Props를 사용 가능 • 대신 WithoutRef가 붙어있으므로 ref는 사용 불가 • 만약 ref를 사용하고 싶다면 ComponentPropsWithRef T > 사용 components/Button.tsx
  • 82. Button 컴포넌트 만약 추가적인 프로퍼티가 필요하다면? • interface로 Props 타입을 별도로 선언함 • React.ComponentProps button 을 확장하게 함 • 기존 button에 전달할 수 있는 모든 Props를 갖게 됨 • 추가적인 프로퍼티는 interface 내부에 작성 components/Button.tsx
  • 83. Button 컴포넌트 그러나 만약 추가한 프로퍼티가 중복된 이름을 가질 경우 오류 발생 • Props 인터페이스에 type 프로퍼티를 추가 오류 발생 • type은 이미 React.ComponentProps button 타입에 정의됨 • 타입스크립트는 이를 동일한 프로퍼티의 타입을 재 정의하는 것으로 해석 • 확장된 인터페이스에서 프로퍼티의 타입을 재 정의할 때에는 슈퍼 타입에 정의된 타입의 서브 타입으로만 정의할 수 있음 components/Button.tsx
  • 84. Button 컴포넌트 Omit T, K > 유틸리티 타입을 이용 • Omit T, K > 는 T 타입으로 부터 K에 해당하는 프로퍼티를 제외하는 타입 • Omit React.ComponentProps button , type 은 React.ComponentProps button 으로부터 type 프로퍼티를 제외 하는 타입을 반환함 • type 프로퍼티를 제외하고 확장하기 때문에 오류가 발생하지 않음 components/Button.tsx
  • 85. Button 컴포넌트 추가해야 하는 프로퍼티가 많고 다양하다면? • Props 인터페이스는 아무것도 확장하지 않도록 변경 • Button 컴포넌트의 props의 타입으로 Props Omit … 타입 정의 • Omit React.ComponentProps button , keyof Props 타입? • React.ComponentProps button 으로부터 Props 타입에 존재하는 프로퍼티들을 제외한 타입을 추출 components/Button.tsx
  • 86. ButtonLink 컴포넌트 ButtonLink.js -> ButtonLink.tsx • Props 타입을 인터페이스로 선언 • Next.js 내장 타입인 LinkProps 타입을 확장하도록 설정 • LinkProps 타입은 Link 컴포넌트에 전달할 수 있는 Props들 이 선언되어 있는 타입 components/ButtonLink.tsx
  • 87. Container 컴포넌트 Container.js -> Container.tsx • Props 타입을 인터페이스로 선언 • children 타입을 React.ReactNode 내장 타입으로 정의 • ReactNode는 React의 children으로 사용될 수 있는 거의 모 든 타입을 포함하는 범용적인 타입임 components/Container.tsx
  • 88.