TypeScript

gjeon·2021년 12월 11일
0

TypeScript

목록 보기
1/2
post-custom-banner

TypeScript란?

  • JavaScript를 기반으로 한 프로그래밍 언어이다.
  • JavaScript와는 다른 프로그래밍 언어라 할 수 있다.(완전 다른건 아니다. TypeScript는 JavaScript를 기반으로 하기 때문이다.)
  • JavaScript와 거의 같은데 새로운 기능을 살짝 추가한거라 볼수있다.
  • strongly-typed 언어이다.
  • 브라우저는 TypeScript 언어를 못알아 듣는다. 그래서 확인후 이상이 없으면 JavaScript로 반환해준다.

strongly-typed

프로그래밍 언어가 작동하기 전에 type을 확인하는 것이다.

const plus = (a, b) => a + b;

를 예로 들면 a와 b가 어떤 타입으로 들어갈지 JavaScript는 정해져있지 않다.
하지만 strongly-typed 언어인 TypeScript는 프로그램이 작동하기전에 데이터의 타입을 확인해줘서 좀 더 안전하게 작업을 할 수 있다.

위의 코드를 TypeScript로 바꾸면

const plus = (a:number, b:number) => a + b;

a와 b는 number 타입을 가져야 되다는 말이다.
이렇듯 마이웨이인 JavaScript와 다르게 TypeScript는 작은 실수로부터 우리를 보호해준다.

TypeScript로 React 시작하기

  1. TypeScript 설치
    처음 시작에 두 가지 방법이 있다.
    npx create-react-app my-app --template typescript
    or
    yarn create react-app my-app --template typescript
    위의 방법은 처음 리액트 앱을 만들때 --template typescrip 를 추가해서 생성하는 것이다.
    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
    두 번째 방법은 기존 앱에 필요한 모듈들을 설치해 주는 것이다.
  2. 아래의 방법으로 TypeScript 모듈을 설치했다면
    확장자를 변경해줘야된다.
    React, TypeScript 에서는 확장자 .js 를 사용하지 않고 .tsx 를 사용한다.
    (TypeScript는 .ts)
  3. 모듈 설치
    일반적인 js모듈을 설치해서 사용하면 typescript는 사용하지 못한다.
    예를 들어
    npm i styled-components
    로 모듈을 설치하고 TypeScript 에서 사용하려하면 사용이 안되는데 이유는 styled-components 가 javascript 로 되어있기 때문인데, 이걸 되게 하려면
    npm i --save @types/styled-components
    를 사용해 설치해주면 된다.

@types 란?
매우 큰 Github repository로 유명한 npm 라이브러리를 사람들이 모여서 TypeScipt에서 사용 가능하게 type definition을 만들어놓은 저장소이다.
https://github.com/DefinitelyTyped/DefinitelyTyped

만약 TypeScript 선언이 없는 모듈을 import 한다면?
npm i --save-dev $types/[모듈 이름] 을 입력해서 확인을 하자.
Github repository 에서 검색하는건 추천하지 않는다. 대부분에 파일이 숨겨져 있기때문.

interface

Object 형식으로 타입을 정의해서 사용할 수 있다.

interface PlayerShape {
	name: string;
  	age: number;
};
const sayHello = (playerObj: PlayerShape) => 
	`Hello ${playerObj.name} you are ${playerObj.age} years old.`;
sayHello({name: "gjeon", age:12});
sayHello({name: "hi", age:30});

propTypes 와 매우 유사하지만 interface는 TypeScript와 코드가 실행되기 전에 확인해 준다는 차이점이 있다.

Optional Props

위의 interface를 보면 무조건 정의된 인자가 들어와야하고 기본값이 정해져 있지 않다.

import styled from "styled-components";

interface ContainerProps {
  bgColor: string;
  borderColor: string;
}

const Container = styled.div<ContainerProps>`
  width: 200px;
  height: 200px;
  background-color: ${(props) => props.bgColor};
  border-radius: 100px;
  border: 1px solid ${(props) => props.borderColor};
`;

interface CircleProps {
	bgColor: string;
	borderColor?: string;
	text?: string;
}

function Circle({ bgColor, borderColor, text = "default text" }: CircleProps) {
	return (
		<Container bgColor={bgColor} borderColor={borderColor ?? bgColor}>
		{text}
		</Container>
	);
}

export default Circle;

borderColor?: string 을 보면 : 옆에 ? 가 들어가 있다. 의미는 borderColor 라는 인자가 들어올 수도 있고 안들어올수도 있다는 말이다.

interface 를 두 번 사용했는데 아래 interface에서는 borderColor?: 로 값이 안들어와도 되지만 styled-components의 Container 는 borderColor:를 필수로 필요로 하기에 에러가 발생한다. 이러한 경우 ??를 사용할수도 있다.
<Container bgColor={bgColor} borderColor={borderColor ?? bgColor}>
borderColor ?? bgColor ??은 borderColor의 값이 undefined 일 경우 bgColor 값으로 적용돼서 borderColor=bgColor가 되어 props로 넘겨준다.

{ bgColor, borderColor, text = "default text" }
text가 비어있을 경우 "default text"가 값으로 적용되어 들어가는 것으로 javascrip이다.

State

TypeScript로 useState()를 사용하면 default값을 통해 타입을 정의해준다.

const [counter, setCounter] = useState(1);

default 값으로 1이 들어가서 counter는 number라고 정의된다. 그리고 setCounter도 number를 사용하는 액션이라는 것을 알 수 있다.
이처럼 초기값으로 유추하여 타입을 정의한다.

하지만 다른 타입으로 바뀌는걸 원한다면 아래와 같이 작성한다.

const [counter, setCounter] = useState<number|string>(1);

counter는 number 또는 string 이라는 의미이다.

Forms

import React, { useState } from "react";

function App() {
  const [value, setValue] = useState("");
  const onChange = (event: React.FormEvent<HTMLInputElement>) => {
    const {
      currentTarget: { value },
    } = event;
    setValue(value);
  };
  const onSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log("hello", value);
  };
  return (
    <div>
      <form onSubmit={onSubmit}>
        <input
          value={value}
          onChange={onChange}
          type="text"
          placeholder="username"
        />
        <button>Log in</button>
      </form>
    </div>
  );
}
export default App;

event: React.FormEvent<HTMLFormElement>와 같이 생소한 부분이 나온다.
event의 타입도 정의해줘야 되는데 이때 'any' 타입이 올수도 있다. 'any' 타입은 어떤 타입이든 올 수 있다는 말인데, 가능한한 any 타입은 배제하고 이제 무슨 타입인지를 쓰거나 설명하고자 노력해야 한다고 한다.
이때 event에 타입을 추가하는 방식이
React.FormEvent<HTMLFormElement>이다.
상황에 따라 어떤 종류의 Element에 따라 이벤트가 실행될지를 나타낸 것이다.
event 타입을 정의해주는 것을 제외한 나머지는 JavaScript + React 와 같다.

ReactJs 내의 TypeScript로 작업을 할때 어디에 타입이 있는지 어떤 타입을 넣어야 되는지 구글링을 많이 해야된다.React 이벤트 가이드

Themes

themes 를 사용할 때 타입을 정의하는것을 해보자.
styled-components theme과 typescript를 연결하는 지시를 따라한다.
Create a declarations file
https://styled-components.com/docs/api#create-a-declarations-file
선언 파일을 만들어준다. (.d.ts로 끝남)

//styled.d.ts
import "styled-components";

declare module "styled-components" {
  export interface DefaultTheme {
    textColor: string;
    bgColor: string;
    btnColor: string;
  }
}

이렇게 생성한 파일은 우리가 이전에 @types/styled-components를 통해 설치한 index.d.ts 파일을 확장한다.

//theme.ts
import { DefaultTheme } from "styled-components";

export const lightTheme: DefaultTheme = {
  bgColor: "white",
  textColor: "black",
  btnColor: "tomato",
};

export const darkTheme: DefaultTheme = {
  bgColor: "black",
  textColor: "white",
  btnColor: "teal",
};

병합된 DefaultTheme를 import해서 불러온뒤 타입으로 정의해서 사용한다.

//index.tsx
import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";
import { darkTheme, lightTheme } from "./theme";

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

나머지는 javascript에서 theme을 사용하는 것과 같다.

declaration merging(병합 선언)
https://www.typescriptlang.org/docs/handbook/declaration-merging.html

Reference

https://nomadcoders.co/react-masterclass
https://create-react-app.dev/docs/adding-typescript/
https://dev.to/rajuashok/create-styled-d-ts-to-make-typescript-work-with-styled-components-5dk4

profile
개발자 되기
post-custom-banner

0개의 댓글