개발

TypeScript

썽연 2022. 5. 26. 21:08
728x90

3. 타입스크립트

TypeScript

  • JavaScript기반 프로그래밍 언어
  • 다르지만, 다르지 않다!
  • JS 기반 + 기능 살짝 추가
  • 작동 전, Type을 확인한다.
const plus = (a,b) => a+b;

위의 코드는 자바스크립트 코드이다.

plus(2, "hi") // 2hi 

우리는 위와 같이 plus함수는 숫자를 더해주는 함수로, 잘못된 정보인 것을 알고싶다!

그래서~~ 타입스크립트로 타입을 먼저 지정해주자!

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

위 코드는 자바스크립트와는 약간 다르다!
plus함수인데, 숫자가 들어가야한다는 것을 명시해준 것이다.
즉, 그래서 우리는 앞으로 plus의 파라미터로는 숫자를 받아야한다!

plus(2, "hi") // Argument of type 'string' is not assignable to parameter of type 'number'

위의 코드는 에러가 뜰 것이다.

왜냐?
우리는 숫자라고 타입을 지정해줬는데, 문자열을 입력했기 때문에!
숫자로 변경해주자~~

리액트에 타입스크립트를 같이 사용해보자

yarn create react-app (폴더명) **--template typescript**

재설치 이후, styled-component 설치 및 theme 설정해주자!

이미 프로젝트 파일이 있다면?

자세한 방법은 아래를 참고해보자 (리액트 18버전)
리액트를 타입스크립트로 변환해보자!

TypeScript에서 Props 받는 방법을 알아보자

PropTypes의 Props

  • prop이 있는지 없는지 확인
  • 코드를 실행한 ‘후'에 오류 확인이 가능하다

TypeScript의 Props

  • 코드가 실행되기 ‘전’에 오류 확인이 가능하다!

그렇다면 TypeScript에서 props를 주는 방법은?
interface를 통해서 객체타입이 무엇인지 먼저 지정해준다

interface가 뭔데??
object shape(객체 모양)을 TypeScript에게 설명해주는 것!

interface CircleProps {
  bgColor: string;
}

function Circle({ bgColor }: CircleProps) {
  // bgColor의 타입은 CircleProps의 Object이다!
  return <Container bgColor={bgColor} />;
}

위 코드처럼 CricleProps를 객체형태로 타입을 지정해준다.
bgColor이 CircleProp의 object로 있기 때문에, prop으로 줄 수 있다!

여기서 bgColor의 효과는 배경색인데, 스타일 컴포넌트에서 배경색을 props로 받아야한다!

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

우리는 styled-components에서 props를 받을 때, background-color: ${(props) => props.bgColor}; 와 같은 코드를 사용하였다.

타입스크립트에서는 해당 타입이 무엇인지 알아야하므로 interface해준 변수명을 <>에 작성해준다!

해당 props를 지정해주었기 때문에 Container는 Props를 받는다!

function Circle({ bgColor }: CircleProps) {
  // bgColor의 타입은 CircleProps의 Object이다!
  return <Container bgColor={bgColor} />;
}
function Circle({ props }: CircleProps) {
  return <Container bgColor={props.bgColor} />;
}

props를 받는 두가지의 방법이며, 같은 기능을 하는 코드이다. (보통 위의 방법을 선호한다.)
props로 배경색을 컴포넌트 호출할 때 지정해줄 수 있다.

function App() {
  return (
    <>
      <Circle bgColor="teal"></Circle>
      <Circle bgColor="tomato" />
    </>
  );
}

만약 여기서 props를 주지 않는다면?

  • 현재 props는 required이기 때문에 에러가 나타날 것이다!

그렇다면 optional props를 주는 방법은?

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

borderColor처럼 ?를 붙여주면 된다!
?를 붙여줌으로써 string이거나 undefined를 뜻한다!

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;
}

function Circle({ bgColor, borderColor }: CircleProps) {
  // bgColor의 타입은 CircleProps의 Object이다!
  return <Container bgColor={bgColor} borderColor={borderColor **?? bgColor**} />;
}
//위와 같은 코드임!
// function Circle({ props }: CircleProps) {
//   return <Container bgColor={props.bgColor} />;
// }

export default Circle;

위 코드에서 ContainerProps의 borderColor의 타입은 string으로 알고 있는데,

?? bgColor 를 해주지 않는다면 빨간줄로 에러가 뜰 것이다.

왜 에러가 뜰까?
CircleProps에서 borderColor의 값이 undefined일수도 있기 때문이다!

그래서 우리는 borderColor의 값이 없다면 bgColor를 borderColor로 기본값을 지정해주는 코드를 작성했다!

TypeScript에서 State 사용법

React에서 쓰는 방법처럼

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

로 사용하면 된다.
이때 counter는 초기값 0에 의해 number 타입이라고 예측하고 있기에, 우리는

setCounter('hello');는 에러가 발생할 것이다.

즉, 타입스크립트는 자연스럽게 초기값에 의해 값을 추측한다!

하지만 문자열 또는 숫자를 받고싶다면? 어떻게해야할까?

const [value, setValue] = useState<number | string>(0);와 같이 초기값을 주기 전에 <> 사이에 타입을 | 로 지정해주면 된다!

setValue("hello");
setValue(2);

위 두 코드는 문자열로 변경하거나, 숫자로 변경하는데 에러가 뜨지 않을 것이다.

단, setValue(false)와 같이 지정해주지 않은 타입을 쓰면 에러가 뜬다!

Form을 사용하면서 input의 value를 state와 연결해보자

먼저, useState를 이용하여 state의 값을 만들고, input이 변할 때 마다 state의 값이 적용되어야 한다!

그래서 onChange 함수를 만들자~~

onChange는 event값을 받고, 이 값의 타입을 타입스크립트가 FormEvent를 받고, HTMLInputElement에 의해서 실행될 것을 알게 되었다.

코드는 다음과 같다.

const  [userName, setUserName] = useState("");
const onChange = (event:React.FormEvent<HTMLInputElement>) => {
    const {
        currentTarget: {value},
    } = event;
setUserName(userName);
};
const onSubmit = (event:React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
};

return(
    <>
        <form onSubmit={onSubmit}>
            <input value={userName} onChange={onChange} type="text" placeholder="username"/>
            <button>Login</button>
        </form>
    </>
)

TypeScript에서 styled-components를 연결해보자!

theme을 사용하여 테마를 지정해보자

//src/styled.d.ts

import 'styled-components';

declare module 'styled-components' {
    export interface DefaultTheme {
        textColor: string;
        bgColor: string;
        btnColor: string;
    }
}
// src/theme.ts

import { DefaultTheme } from "styled-components"

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

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

index.tsx에서

<App/><ThemeProvider theme={lightTheme}> 로 감싸주는 것을 잊지말자!

// src/App.tsx

import { useState } from "react";
import styled from "styled-components";

const Container = styled.div`
  background-color: ${(props) => props.theme.bgColor};
`;
const H1 = styled.h1`
  color: ${(props) => props.theme.textColor};
`;

function App() {
  return (
    <Container>
      <H1>protected</H1>
    </Container>
  );
}

export default App;

위의 코드에 맞게 App.tsx를 수정해주자
index.tsx의 theme에 따라 배경색상과 글씨 색상이 바뀌는것을 확인할 수 있다.

728x90