TS - 리액트 타입스크립트로 적용하기

moontag·2022년 9월 16일
11

TypeScript

목록 보기
1/4

TS 왜 쓰는가?

JavaScript

  • Dynamic Typing으로 밑과 같은 경우에도 에러 발생 안함
    ex) 1 + '2' = 3 가능
  • 런타임 에러 발생 가능

TypeScript

  • type을 엄격히 검사하여 에러메시지를 정확히 짚어줌
    ex) 1 + '2' = 에러 출력해줌
  • 런타임 에러 예방
    런타임 전(코드를 실행하기 전)에 에러를 잡을 수 있음
  • 브라우저에서 자바스크립트로 변환됨
  • 타입 추론, 타입 명시 가능
    https://www.typescriptlang.org/





1. TS설치

공식문서

  • CRA 리액트와 같이 TS설치
npx create-react-app my-app --template typescript
or
yarn create react-app my-app --template typescript
  • 기존 CRA 리액트가 존재할때 TS만 추가하기
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
or
yarn add typescript @types/node @types/react @types/react-dom @types/jest



tsconfig.json 생성

  • npx typescript --inittsc --init해서 tsconfig.json 생성
    • 환경설정을 밑처럼 작성해야 build시 ts => js로 컴파일 가능해짐
  • compilerOptions
    설정옵션 공식문서
    include : 컴파일할 파일 경로 설정
    exclude : 컴파일에서 제외하는 대상
    compilerOptions : 컴파일할 때 적용되는 옵션들
    • target : 어떤 버전으로 컴파일할 것인지 작성
    • module : 어떤 모듈 방식으로 컴파일할지 설정
{
  "compilerOptions": {
    "target": "es6", //어떤버전의 js로 컴파일할지 정의
    "lib": [ //어떤 환경에서 사용하는지 정의(api자동완성 제공해줌)
      "dom", //브라우저
      "dom.iterable",
      "esnext"
    ],
    "baseUrl": "./src", // 추가된 것 ./src를 절대 경로로 지정
    "allowJs": true, //ts안에서 js허용(js파일 import가능)
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [ //컴파일할 폴더 입력. src의 모든파일 확인함
    "src"
  ],
  "exclude": [
    "node_modules"   
  ],
}



파일 수정

  1. .jsx.js 확장자 파일 => .tsx로 확장자 변경

  2. index.js => index.tsx 파일명,내용 변경

에러

  • React 18이 나오면서 밑에껀 구버전이므로 콘솔에 에러가 뜬다
    • ReactDOM.render 말고 대신에 createRoot 사용하라는 문구
// 에러 메시지
react-dom.development.js:86 Warning: ReactDOM.render is 
no longer supported in React 18. Use createRoot instead.
Until you switch to the new API, your app will behave as 
if it's running React 17
// 구버전
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

해결방법

  • 1) 우리가 적용한 것 - ! 추가
    콘솔창 에러링크를 클릭했을 때
    createRoot(container!) if you use TypeScript문구에서
    createRoot(content!)구조를 보고 ! 추가
    • TS는 createRoot안에서 null을 반환할 수 없는데,
      !을 붙여서 null이 아닐때로 설정하는 것
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • 2) 또 다른 방법 - as HTMLElement 추가
    getElementById로 받는 객체 타입을 지정해서 TS가 데이터 타입을 알 수 있게 해줌.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);



  1. App.js => App.tsx 파일명,내용 변경
import React from 'react';
import './App.css';

const App: React.FC = () => {
  return (
      <div className="App">
        Hello Typescript
      </div>
  );
}

export default App;



라이브러리

styled-components, redux, react-router-dom과 같은 라이브러리를 사용했다면 밑과 같은 에러문이 뜨는데

  • styled-components
    npm install --dev @types/styled-components
    에러에서 설명하는 순서대로 @types/라이브러리 설치하면 된다









2. eslint 설정

  • 프로젝트에서 설치
npm install -D eslint
  • 프로젝트 root폴더에서 입력
npx eslint --init
  • 터미널 입력 창 뜸
  • How would you like to use ESLint?
  • What type of modules does your project use?
  • Which framework does your project use?
  • Does your project use TypeScript? (y/N)
    => Y
  • Where does your code run? (Press space to select, a to toggle all, i to > invert selection)
    What format do you want your config file to be in? (Use arrow keys)
  • The config that you've selected requires the following dependencies:
    @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
    Would you like to install them now with npm? (Y/n)
    => Y
  • eslintrc.json생성됨
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:import/recommended",
    "plugin:jsx-a11y/recommended",
    "plugin:prettier/recommended"
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "rules": {
    "react/react-in-jsx-scope": 0,
    "react/jsx-uses-react": 0
  }
}

3. prettier 설정

  • prettier 설치
npm install -D eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-prettier eslint-config-prettier
  • eslint-plugin-import : ES6의 import, export 구문을 지원, 필수 플러그인
    eslint-plugin-react : React 규칙이 들어있는 플러그인
    eslint-plugin-react-hooks : React Hooks 규칙이 들어있는 플러그인
    eslint-plugin-jsx-a11y : JSX요소의 접근성 규칙에 대한 정적 검사 플러그인

  • root폴더에서 .prettierrc 생성

  • 설정 옵션 참고 링크





4. TS 간단히 시작하기

  • 변수명 : type명
  • type명 종류
    string, number, boolean, bigint, null, undefined, [], {}
const 변수명 :string = 'mun'
변수명 = 119;  //타입이 변경되면 에러메시지 출력해줘서 버그 줄일수있음
  • | 로 여러타입 지정 가능
let 변수명 :string | number = 'mun';
  • 배열, 객체 타입 지정
let 숫자 : string[] = ['one', 'two'];
let 나이 : {age : number} = {age : 1}
  • type키워드로 변수처럼 사용 가능
type nameType = string | number;
let 이름 : nameType = 'kim';
  • 함수 매개변수type과 리턴type 지정
  • 리턴type에 void 설정가능 - return이 없는지 체크하는 타입
function 함수명(a :string) : string{
  return '안녕';
}
  • 타입이 명확해야 연산가능해짐
//에러
function 함수명(x :number | string) {
  return x * 2
}

//가능
function 함수명(x :number | string) {
  if (typeof x === 'number'){
    return x * 2
  } 
}
  • type 키워드에 [] 배열 안 순서에 맞게 타입 지정하기
type Info = [number, boolean];
let mun:Info = [100, false]

type or interface로 중복되는 객체타입 지정

  1. type 키워드나 interface 키워드로 객체 타입 지정 가능
  • 프로젝트에서는 객체타입지정으로 type과 interface 둘 중에 하나만 사용하여 일관성 유지하기
  • 특정속성이 선택적(필수가 아닌 것)이면 속성명? 사용 가능
interface UserInfo1 {
  name : string,
  age : number
}
type UserInfo2 = {
  name? : string,  //속성이 필수가 아니고 선택적일때 ? 사용
  age : number
}
let 회원명 :UserInfo1 = { 
  name : 'mun',
  age : 30
}
  • 객체 안 모든 속성 타입이 같다면 전체타입 지정 가능
type UserInfo = {
  [key :string] : number,
}
let 철수 :UserInfo = { 
  age : 30,
  weight : 80,
}

interface export확장하기

  • interface가 반복사용될때 export하고 extends로 사용하기
/*확장*/
//People.tsx
export interface PeopleInterface {
  name: string
  age: number
}

interface StudentInterface extends PeopleInterface {
  school: string
}
/*외부 컴포넌트 사용*/
import PeopleInterface from "People.tsx";
const cmp:React.FC=()=>{
	const [people, setPeople]=useState<PeopleInterface>();
}



함수의 return 타입 지정하기

// 함수선언식
function Maker(name:string) : Player{
  return {
    name:name
  }
}
// 함수표현식, 화살표함수
const Maker = (name:string): Player => ({name})
const nico = Maker("nico")
nico.age = 12

5. 리액트에서 TS사용하기

React와 React+TS 의 차이점

  • React+TS : state, props, function, event 등에 타입 선언해줌

useState

// 리액트
const [state, setState] = useState('초기값')

//✅ 리액트 + TS
const [state, setState] = useState<string>('초기값')



1. React.FC 있는 경우 단점

  1. props에 children 기본적으로 담겨있음
    • 단점 : 어떤 컴포넌트엔 children 필요없음
  2. defaultProps 제대로 작동 안됨
import React from 'react';

type GreetingsProps = {
  name: string;
};

const Greetings: React.FC<GreetingsProps> = ({ name }) => (
  <div>Hello, {name}</div>
);

export default Greetings;



2. React.FC, 화살표함수 없는 경우

  • React.FC생략하면 defaultProps 제대로 작동
  • 화살표함수말고 function 키워드 사용가능
import React from 'react';

type GreetingsProps = {
  name: string;
  mark: string;
  option?: string;
};

function Greetings({ name, mark }: GreetingsProps) {
  return (
    <div>
      Hello, {name} {mark}
    </div>
  );
}

Greetings.defaultProps = {
  mark: '!'
};

export default Greetings;



Props







참고

https://github.com/typescript-cheatsheets/react

[React] create-react-app & Typescript 초기 세팅 완벽 정리

https://haerang94.tistory.com/155

https://memostack.tistory.com/281#1.1.%20Typescript%20%EC%9D%98%EC%A1%B4%EC%84%B1%20%EC%B6%94%EA%B0%80

코딩애플 - Typescript 필수문법 10분 정리와 설치 셋팅 (Vue, React 포함)

profile
터벅터벅 나의 개발 일상

0개의 댓글