TypeScript with React

fromzoo·2021년 3월 10일
1

Introduction to Typescript

interface IHuman {
	name: string,
	age?: number,
	hungry:boolean
}

age?: number에 optional value 값을 준 것.
age는 number이거나 undefined이다.

Typescript and React Introduction

cratypescript 설치

$ npx create-react-app 프로젝트명 --typescript

typescript로 설치하면 jsx, js파일 확장자는 tsx, ts로 선언된다.

🧨 but 타입스크립트 확장자가 아닌 기존과 똑같이 자바스크립트 확장자로 나온다?!?

$ npx create-react-app 프로젝트명 --template typescript

--template를 추가해서 다시 설치해보자.

tsconfig.json

  • tsconfig에는 타입스크립트에 필요한 룰이 존재
    - create-react-app에 --typescript를 적용해서 프로젝트를 생성했기 때문

  • noImplicitAny : false
    - 변수에 타입을 선언해주지 않아도 에러가 발생하지 않음

definitelyTyped

  • npm js에 속한 많은 라이브러리들이 있는 디렉토리
  • 개발자들을 위한 수많은 type과 inteface가 있다.
  • styled-component를 import 해오면 타입에러가 발생
    - styled는 아무 타입도 갖고있지 않다고 나옴
    - but definitelyTyped에 styled-component의 type을 만들어놨기 떄문에 명령어창에 설치만 하면 됨
$ npm i @types/styled-components
import styled from 'styled-components'; 

설치를 하고나면 styled-components에 에러가 뜨지않고, import해온 styled는 모든 type을 가질 수 있게 된다.

타입스크립트가 styled-components의 모든 타입을 알고있는 상태기 때문이다.

때문에 만약

import {createGlobalStyled} from 'styled-components';

createGlobalStyled.hello;

createGlobalStyled.hello로 실행하면 createGlobalStyled에는 hello의 타입이 없는 것을 타입스크립트가 알고있기 때문에 에러를 발생시킨다.

즉 내가 실수할 수 있는 가능성을 막아주는 것이다.

유용한 라이브러리는 사용하고 싶을 경우에

$ npm i @types/라이브러리명

으로 설치해서 타입을 선언해주자.

@types가 제공되지 않는 라이브러리라면?

tsconfig.json

"noImplicitAny": true

'이것의 코드에 타입이 없는 경우도 있는데 이건 type을 찾지 못한 것이다.' 라는 의미

definitelyTyped는 유명한 라이브러리만 제공해주기 때문에 알아두는 것이 좋다.

React State and Typescript

Comopnent Typescript 초기 설정

class Components <P = {}, S = {}, SS = any>

  • P란? props
  • S란? state

interface설정

interface IState {
	counter:number
}

class  App  extends  Components <{},IState> {
	...
}

Interface 변수는 대문자로 시작하는게 좋다.

React Props and Typescript

클래스형과는 달리 함수형 컴포넌트같은 경우에는 React.FunctionComponent를 사용해서 타입스크립트의 초기 타입을 선언해준다.

interface IProps {
	count:number
  
const Number:React.FunctionComponent<IProps> = ({count}) => (
	<Container>{count}</Container>
)

인터페이스를 사용하고 싶지 않은 경우에는

<{ count : number }>

위처럼 바로 객체형태로 타입을 선언해줄 수 있다.

React Events and Typescript

children

  • 기본적으로 모든 리액트 컴포넌트는 children이라고 하는 prop을 갖는다.
  • React.ReactNode : children의 타입

function Type

interface IProps {
	onChange:  ()  =>  void
}

onChange event Type

onChange 함수로 input의 value를 접근하기 위해서는 event arguments를 사용해야한다.

but 타입을 지정하지 않으면 onChange함수에서 에러가 발생.

interface IInputProps {
	onChange:  (event:  React.SyntheticEvent<HTMLInputElement>)  =>  void
}

event arguments에 React.SyntheticEvent<HTMLInputElement>로 타입을 선언

onChange  =  (event:React.SyntheticEvent<HTMLInputElement>)  => {
	console.log(event.target);
}

onChange함수에도 그대로 적용

Input 타입을 명시해줬기 때문에 input이 아닌 select나 다른 엘리먼트로 적용하면 에러가 난다.

이렇게 타입스크립트는 event를 정확하게 다룰 수 있도록 도와준다.

onSubmit event Type

React.FormEvent

부모컴포넌트

onFormSubmit  =  (event:React.FormEvent)  => {}

자식컴포넌트

interface IFormProps {
	onFormSubmit :  (event:React.FormEvent)  =>  void
}

const Form:React.FunctionComponent<IFormProps> = ({onFormSubmit}) => (
	<form  onSubmit={onFormSubmit}>...</form>
)

Styled Components and Typescript

const Container = styled.span<{isBlue:boolean}>`
	color:${props  =>  props.isBlue  ?  'blue'  :  'black'  };
`

const Number:React.FunctionComponent<IProps> = ({count}) => (
	<Container  isBlue={  count  >  10  }>{count}</Container>
)

styled-component는 inline으로 작성
함수형, 클래스형 컴포넌트는 interface로 작성

코드 작성하다보면 interface가 그만큼 많아지고 복잡해짐
styled-component와 함수, 클래스형 컴포넌트가 섞일 수도 있기때문에 분리해서 작성하는 것을 추천한다고 한다.

Theme

styled-components에서 theme은 variable을 정의하는 방법이다.
매번 복사, 붙여넣기하기 번거롭기 때문에 사용한다.

theme과 ThemeProvider로 정의
theme.ts

export  default {
	blueColor:'red'
}

index.tsx

import {ThemeProvider} from  'styled-components';
import theme from  './theme'

ReactDOM.render(
	<ThemeProvider  theme={theme}>
		<App  />
	</ThemeProvider>,
	document.getElementById('root')
);

컴포넌트 styled-component에 적용

const Container = styled.span<{isBlue:boolean}>`
	color:${props  =>  props.isBlue  ?  props.theme.blueColor  :  'black'  };
`

styled.d.ts

styled.d.ts를 이용해서 theme을 자동완성 시켜줄 수 있다.

여기서 d는 definition
즉, 타입스크립트를 위해서 무언갈 정의한다는 뜻이다.

import  'styled-components';

declare  module  'styled-components' {
	export  interface DefaultTheme { // 정의할 Theme
		blueColor:string // 원하는 속성의 타입 선언
	}
}

출처

profile
프론트엔드 주니어 개발자 🚀

0개의 댓글