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에 따라 배경색상과 글씨 색상이 바뀌는것을 확인할 수 있다.