타입스크립트를 사용하고 싶은데, 이미 리액트 프로젝트가 있다면?
yarn add typescript @types/node @types/react @types/react-dom @types/jest
의 코드를 이용하여 타입스크립트를 추가하자
타입스크립트에선 .js파일이 아닌 .ts파일이므로
리액트에서 사용할 수 있도록 .tsx로 확장자를 변경해주자
styled-components
역시 typescript에서 호환할 수 있도록yarn add -D @types/styled-components
를 해주자!
즉, 순서는 다음과 같다
1. 타입스크립트 yarn add 해주기
2. 타입스크립트 확장자 변경
3. js에서 사용하던 라이브러리 타입스크립트와 호환할 수 있도록 설치해주기 (styled-components 등)
타입스크립트의 환경구성을 위해 tsconfig.json파일을 추가하자
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"baseUrl": "./src",
"types": ["react/next", "react-dom/next"],
"paths": {
"~page/*": ["pages/*"],
"~lib/*": ["lib/*"],
"~DesignSystem/*": ["DesignSystem/*"],
"~/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next.config.js", "tailwind.config.js"],
"exclude": ["node_modules"]
}
react-app-env.d.ts
/// <reference types="react-scripts" />
로 변경을 해주자 ~~
노마드코더 영상에서는 이렇게하면 실행이 잘 되었지만,
리액트 18버전으로 업데이트가 되면서 index.tsx에 에러가 발생했다.
index.tsx는 다음과 같았다.
import React from 'react';
import ReactDOM from "react-dom/client";
import { ThemeProvider } from "styled-components";
import App from './App';
const darkTheme = {
textColor: "whitesmoke",
backgroundColor: "#111",
};
const lightTheme = {
textColor: "#111",
backgroundColor: "whitesmoke",
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
);
하지만, 여기서 타입스크립트에 대한 에러가 떴다. jsx라면 잘 실행이 되었을 것이다!
Property 'createRoot' does not exist on type 'typeof
import("/code/my-app/node_modules/@types/react-dom/index")'. TS2339
해당 오류는 타입유형에 createRoot의 속성이 없어서 생긴것이다.
그래서 우리는 타입스크립트에 맞게 react와 react-dom을 추가해주어야한다!
yarn add @types/react @types/react-dom
을 이용하여 타입스크립트와 호환하도록 라이브러리를 추가해주자
오류가 바껴서 다른 에러가 뜨는 모습을 확인할 수 있다.Type 'null' is not assignable to type 'Element | DocumentFragment'.
위 오류는 타입스크립트에서 null을 반환할 수 없다는 뜻이므로, index.js코드를 다시 한 번 수정해주자!
최종 코드는 다음과 같다
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { ThemeProvider } from "styled-components";
const darkTheme = {
textColor: "whitesmoke",
backgroundColor: "#111",
};
const lightTheme = {
textColor: "#111",
backgroundColor: "whitesmoke",
};
const rootElement = document.getElementById("root");
if (!rootElement) throw new Error("Failed to find the root element");
const root = ReactDOM.createRoot(rootElement);
root.render(
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
);
rootElement가 없을때의 조건문을 줘서 null일 때 에러를 던지게 만들어서 해결해주었다.
참고자료
https://velog.io/@seungmini/TypeScript%EC%97%90-React18-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0
https://blog.logrocket.com/how-to-use-typescript-with-react-18-alpha/