Typescript 사용법
# 리액트 + 타입스크립트 프로젝트 생성 명령어
npx create-react-app 프로젝트명 --template typescript
예) npx create-react-app frontend-react --template typescript
# 타입스크립트 : 마이크로소프트(깃허브, vscode, typescript, 윈도우 등)
# why? 1) 단점 : js 는 type(자료형)을 정의하지 않고 자유롭게 변수의 값을 넣어 코딩함
# (코딩이 간략/코딩 생산성 증가, 코딩시 에러를 잡지못하고 서비스때 심각한 에러가 발생함)
# 타입스크립트 : js 에 자료형을 명시해서 코딩하게 해주는 js 확장 언어
.tsx로 생성됨
React Typescript폴더 만들고 통합터미널 열어서
npx create-react-app frontend-react --template typescript 입력
assets, pages, types 폴더 생성

App.tsx
사용하고 싶은 태그 주석 해제
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Basic from './pages/Basic';
import BasicExam from './pages/BasicExam';
import Func from './pages/01_exam/Func';
import FuncExam from './pages/01_exam/FuncExam';
import Etc from './pages/02_exam/Etc';
import Counter from './pages/03_exam/Counter';
import Book from './pages/04_exam/Book';
import WebtoonExam from './pages/04_exam/WebtoonExam';
function App() {
return (
<div className="App">
{/* 자식컴포넌트(페이지) 추가 */}
{/* <Basic /> */}
{/* <BasicExam /> */}
{/* <Func/> */}
{/* <FuncExam/> */}
{/* <Etc/> */}
{/* <Counter/> */}
{/* <Book/> */}
<WebtoonExam/>
</div>
);
}
export default App;
Basic.tsx
// Basic.tsx : 자식 컴포넌트(typescript 적용된 버전)
// rfce
import React,{useState} from 'react'
// 새로운 객체타입(자료형) 정의한 파일 import
import IObject from "../types/IObject";
function Basic() {
// TODO: 타입스트립트 기본 사용법 익히기
// 바인딩 변수
// 사용법 : let [변수명, set변수명] = useState<자료형>(초기값); 자료형은 소문자로!
let [message, setMessage] = useState<string>("바인딩 변수 출력입니다.");
let [num, setNum] = useState<number>(0);
let [bflag, setBflag] = useState<boolean>(true);
let [obj, setObj] = useState<IObject>({ id: null, name: "green" });
let [arr, setArr] = useState<Array<number>>([1,2,3,4,5]);
let [objArr, setObjarr] = useState<Array<IObject>>([{id:null, name: "green"}]);
// TODO: 1) 기본 자료형 : 문자열(string), 숫자(number), 참/거짓(boolean), 객체(따로 정의)
// 일반 변수 정의(문자열(string))
// 사용법 : let 변수명: 자료형 = 값;
let message2: string = "일반 변수 출력입니다."; // 문자열
let num2: number = 1; // 숫자형(실수, 정수 모두 포함)
let bflag2: boolean = false; // 참/거짓(bool/boolean)
// TODO: 객체는 자료형을 개발자가 따로 정의해서 사용함
// IObject = { id?: any | null, name: string }
// 설명 : id (any(모든자료형 허용) 또는 null 자료형 허용)
// name (string(문자열만 들어올수 있음))
let obj2: IObject = { id: null, name: "green2" }; // 객체(object)
// TODO: 2) 유니온 사용법 : let 변수명: 자료형(type) | 자료형2 ...
let num3: number | string = 1;
let num4: number | string = "hello";
// let num5: number | string = true; // 에러
// TODO: 3) 옵셔널(?) : 객체의 속성이나 함수의 매개변수에 사용가능
// TODO: 사용하면 오류없이 실행되게 함( 자료형 | undefined 더 붙은 것과 같은 의미)
function hello(name?: string) {
console.log(`안녕하세요 ${name}`);
}
// 함수의 사용
hello("홍길동"); // 안녕하세요 홍길동
hello(); // 안녕하세요
// TODO: 4) 배열 : let 변수: Array<자료형 | 자료형2 ...>
// TODO: 변수 및 함수 사용 시 반드시 정의된 자료형의 값으로 사용하게 강제함
let arr2 : Array<string> = ["a","b","c"]; // 문자열 배열
let arr3 : Array<any> = [1,2,3]; // any(모든 자료형 사용가능) 배열
let arr4 : Array<number> = [1,2,3]; // 숫자 배열
// TODO: 객체배열
let objArr2: Array<IObject> = [{ id: 1, name: "green2"}]; // JSON 문서 형태(객체배열)
return (
<div>
문자(바인딩) : {message}<br/>
문자(일반) : {message2}<br/>
숫자(바인딩) : {num}<br/>
숫자(일반) : {num2}<br/>
불(바인딩) : {bflag? "참": "거짓"}<br/>
불(일반) : {bflag2? "참": "거짓"}<br/>
객체(바인딩) : {obj.name}<br/>
객체(일반) : {obj2.name}<br/>
배열(바인딩) : {arr}<br/>
배열(일반) : {arr2}<br/>
{/* 반복문으로 출력 : .map((value, index)=>()) */}
객체배열(바인딩) : {objArr.map((value)=>value.name)}<br/>
객체배열(일반) : {objArr2.map((value)=>value.name)}<br/>
</div>
)
}
export default Basic
IObject.ts
객체함수는 자료형을 개발자가 따로 정의
// types/IObject.ts : 객체 자료형을 정의하는 파일
// TODO: 타입스크립트 파일명 종류 : .tsx(jsx표현식을 사용한 js) , .ts(jsx표현식 사용안한 js)
// TODO: 리액트의 JSX(Javascript and XML) : {값}
// 사용법 : export default interface 객체자료형명 {
// 속성?: 자료형 | 자료형2 ...,
// 속성2: 자료형
// }
// 속성? : 옵셔널(?) : 속성이 없어도 오류 없이 실행되게 해줌
// 예) let obj: IObject = { name:"홍길동"}
// obj.id (결과는 오류로 출력되지만 에러없이 프로그램이 실행되게 해줌)
export default interface IObject {
id?: any | null,
name: string
}
결과

BasicExam.tsx
// BasicExam.tsx : 자식(연습)
// rfce
import React, { useState } from "react";
function BasicExam() {
// TODO: 변수 정의
const [message, setMessage] = useState<string>(
"안녕하세요 그린컴퓨터아카데미입니다."
);
const [message2, setMessage2] = useState<string>("아래는 곱셈 샘플입니다.");
const [message3, setMessage3] = useState<string>("곱셈");
const [num, setNum] = useState<number>(2);
const [num2, setNum2] = useState<number>(3);
const [sumVal, setSumVal] = useState<number>(num * num2);
return (
<div>
{/* 아래 처럼 바인딩 변수를 사용해서 화면 출력을 하되
타입스크립트 코드를 적용하여 출력하세요
단, 문자는 string , 숫자는 number 를 사용해서 코딩하세요
*/}
{/* 결과 :
안녕하세요 그린컴퓨터아카데미입니다.
아래는 곱셈 샘플입니다.
곱셈
2 * 3 = 6
*/}
{message}<br/>
{message2}<br/>
{message3}<br/>
{num + " * " + num2 + " = " + sumVal}
{/* {num + " * " + num2 + " = " + num*num2} */}
{/* {num} * {num2} = {sumVal} */}
</div>
);
}
export default BasicExam;
결과

Func.tsx
// Func.tsx : 자식 컴포넌트
// rfce
import React, { useState } from "react";
function Func() {
// TODO: 변수 정의
let [name, setName] = useState<string>("");
let [message, setMessage] = useState<string>("");
// TODO: 함수 정의 : typescript 적용
// nfn : 매개변수 2개를 전달받아 messeage 변수에 저장하는 함수
// getInputVal("안녕하세요", 2023)
// TODO: 사용법 : const 함수명 = (매개변수:자료형, ...): 리턴자료형 =>{}
const getInputVal = (arg: string, arg2: number): void => {
setMessage(`${arg} 현재는 ${arg2} 년도입니다.`) // message(화면 바인딩) ` 백틱
}
// 역바인딩(이벤트) 함수 정의
// nfn
// TODO: const 함수명 = (event:이벤트자료형): 리턴자료형 => {}
const onChangName = (event:React.ChangeEvent<HTMLInputElement>): void => {
setName(event.target.value);
}
return (
// TODO: 여기
<div className="container">
<input
className="form-control mt-3 mb-3 w-25"
type="text"
name="name"
value={name}
onChange={onChangName}
/>
입력값 : {name}
<br />
{/* react 아래 onClick={함수명} */}
{/* TODO: 이벤트 함수에 매개변수 있으면 화살표함수를 사용해야함 */}
{/* react 아래 onClick={()=>함수명(매개변수,매개변수2..)}} */}
<button
className="btn btn-primary mt-3 mb-3"
onClick={() => getInputVal("안녕하세요", 2023)}
>
입력값
</button>
<br />
{message}
</div>
);
}
export default Func;
결과

ChangeEvent 함수 사용법
마우스 커서 올리면 예시가 뜬다

Handler 제거 후 붙여넣기
// 역바인딩(이벤트) 함수 정의
// nfn
// TODO: const 함수명 = (event:이벤트자료형): 리턴자료형 => {}
const onChangName = (event:React.ChangeEvent<HTMLInputElement>): void => {
setName(event.target.value);
}
FuncExam.tsx
// FuncExam.tsx : 자식(연습)
// rfce
import React, { useState } from "react";
function FuncExam() {
// TODO: 소스완성하기 : 타입스크립트 적용
// 결과 :
// 입력값 : !Ds1234567890
// 안녕하세요 오늘날짜는 4 일이 맞나요? 답은 true 입니다.
// TODO: 변수 정의
let [message, setMessage] = useState<string>("");
let [password, setPassword] = useState<string>();
// TODO: 함수 정의
const getInput = (arg: string, arg2: number, arg3: boolean): void => { // void 생략 가능
setMessage(`${arg} 오늘날짜는 ${arg2} 일이 맞나요? 답은 ${arg3}입니다`)
}
const onChangPassword = (event:React.ChangeEvent<HTMLInputElement>): void => {
setPassword(event.target.value)
}
return (
// TODO: 여기
<div className="container">
<input
className="form-control mt-3 mb-3 w-25"
type="password"
name="password"
value={password}
onChange={onChangPassword}
/>
입력값 : {password}
<br />
<button
className="btn btn-primary mt-3 mb-3"
onClick={() => getInput("안녕하세요", 4, true)}
>
입력값
</button>
<br />
{message}
</div>
);
}
export default FuncExam;
결과

Etc.tsx
// Etc.tsx : 자식 컴포넌트
// rfce
import React from 'react'
function Etc() {
// TODO: 1) 읽기 전용(readonly) : 값 수정 불가
interface IHello {
readonly name: string
}
let val: IHello = { name: "hello"}; // 초기값 정의
// val.name = "hello2"; // x(readonly) ,수정시 에러
// TODO: 2) 튜플(tuple) : 정해진 자료형의 고정된 크기의 배열
let tuple: [string, number] = ["a", 1];
console.log("tuple", tuple);
// tuple = ["a", 1, 2]; // 값이 3개가 들어와서 에러(x)
// tuple = [1, "a"]; // 자료형 순서가 맞지않음 에러(x)
// TODO: 3) enum : 열거형, 상수를 대체해서 사용함
// TODO: 아래 상수에 자동으로 0 ~ n 1씩 증가되어 저장됨, 값도 직접 지정 가능
enum Week {
Sun, // Sun = 0
Mon, // Mon = 1
Tue, // Tue = 2
Wed = 5, // Wed = 5 (개발자가 강제로 값을 저장)
Thu, // Thu = 6
Fri, // Fri = 7
Sat // Sat = 8
}
console.log("Week", Week);
console.log("Week", Week.Sun);
// TODO: 4) 별명 붙이기
// TODO: 사용법 : type 별명 = 자료형 | 자료형2 ...
// TODO: 사용 : let 변수명 : 별명 = 값;
type aliasUser = string | number;
let person: aliasUser = "hong";
console.log(person);
// TODO: 5) 타입 추론 : 모든 변수에 자료형을 지정하지 않아도 값으로 추론하는 기능을 부여
// TODO: (1) 변수의 초기값 : 생략가능
// let num:number = 10;
let num = 10; // 사용가능
// TODO: (2) 기본값이 있는 매개변수 : 생략가능
// 모던자바스크립트 사용법 : function 함수명(매개변수, 매개변수2=0){}
// 함수의 사용 : 함수명(1) =>함수명(1, 0)
function add(a:number, b = 0):number {
return a + b;
}
// TODO: (3) 리턴자료형는 함수에서 생략가능
function add2(a:number, b = 0) {
return a + b;
}
// TODO: 6) 타입(자료형) 단언 :
// TODO: 활용 : 컴퓨터는 알수없으나 개발자는 확실히
// TODO: 그변수의 자료형을 확신하면 사용가능
// TODO: 사용법 : 변수 as 자료형
function someFunc(val: string|number, isNumber: boolean) {
// 가정 : isNumber 가 true 이면 무조건 val 값은 정수가 된다고 확신
if(isNumber === true) {
(val as number).toFixed(2);
}
}
return (
<div>Etc</div>
)
}
export default Etc
결과

Counter.tsx
// Counter.tsx : 연습(카운팅 예제)
// rfce
import React,{useState} from 'react'
function Counter() {
// TODO: 연습문제 숫자를 감소시키는 함수를 작성하고 화면에 표시하세요
// TODO: 단, 음수값은 화면에 표시하지 마세요
// TODO: 변수정의 : count
let [count, setCount] = useState<number>(0);
// TODO: 함수정의 : setIncreate() , setDecreate()
// + 카운팅 함수
const setIncreate = () => {
setCount(count++);
}
// - 카운팅 함수
const setDecreate = () => {
if(count >= 0) {
setCount(count--);
}
}
return (
<div>
<h3>Counter 예제</h3>
<button onClick={setIncreate}>증가</button>
{/* // TODO: 연습문제 숫자를 감소시키는 함수를 작성하고 화면에 표시하세요 */}
<button onClick={setDecreate}>감소</button>
<p>값 : {count}</p>
</div>
)
}
export default Counter
결과
0 밑으로는 안 내려감

Book
// Book.tsx : 책방 컴포넌트
// rfce
import React, { useState } from "react";
import IBook from "../../types/IBooks";
function Book() {
// TODO: 변수 정의
const initialBooks = [
{
id: 1,
title: "어떻게 배울 것인가",
publisher: "비즈니스북스",
author: "존 맥스웰",
stock: 2,
},
{
id: 2,
title: "신경끄기의 기술",
publisher: "갤리온",
author: "마크 맨슨",
stock: 0,
},
{
id: 3,
title: "부의 미래",
publisher: "청림출판",
author: "앨빈 토플러",
stock: 5,
},
{
id: 4,
title: "기획자의 습관",
publisher: "홍익출판사",
author: "최장순",
stock: 4,
},
];
// 바인딩 변수(객체배열) 정의 : typescript 적용
// TODO: 사용법 : let [변수명, set변수명] = useState<Array<객체자료형>>(초기값);
// TODO: 객체자료형 : 따로 정의(IBook) : 이름규칙(명명법) I이름
let [books, setBooks] = useState<Array<IBook>>(initialBooks); // 객체배열
// TODO: 함수 정의
return (
// TODO: 여기
<div>
<h1>체르니 책방의 도서목록</h1>
<table>
<thead>
<tr>
<th>도서번호</th>
<th>도서이름</th>
<th>출판사</th>
<th>저자</th>
<th>재고량</th>
</tr>
</thead>
<tbody>
{/* 반복문 : 배열변수.map((value, index))=>(<태그>{value.속성명}</태그>) */}
{/* 대상 : 행(<tr><td></td></tr>) */}
{books.map((value, index) => (
// 테이블 tr/td 태그
<tr key={index}>
<td>{value.id}</td>
<td>{value.title}</td>
<td>{value.publisher}</td>
<td>{value.author}</td>
<td>{value.stock}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
export default Book;
IBooks.ts
// IBook.ts : 책방객체명
export default interface IBook {
id?: number,
title: string,
publisher: string,
author: string,
stock: number
}
결과

Webtoon.tsx
// WebtoonExam.tsx : 자식(연습)
// rfce
import React, { useState } from "react";
import IWebtoon from "../../types/IWebtoons";
function WebtoonExam() {
// TODO: 아래 소스를 타입스크립트를 사용하는 예제로 변경하세요
// 1) interface 를 외부 정의해서 사용하세요
// 이름 : IWebtoon.ts
// TODO: 변수정의
const initialWebtoon = [
{
id: 1,
name: "햄스터와 그녀",
isUpdate: true,
},
{
id: 2,
name: "프롬 스타",
isUpdate: true,
},
{
id: 3,
name: "위대한 로맨스",
link: "https://webtoon.kakao.com/content/%EC%9C%84%EB%8C%80%ED%95%9C-%EB%A1%9C%EB%A7%A8%EC%8A%A4/1564",
isUpdate: false,
},
{
id: 4,
name: "빛나는 손을",
isUpdate: false,
},
];
let [webtoon, setWebtoon] = useState<Array<IWebtoon>>(initialWebtoon)
// TODO: 함수정의
return (
// TODO: 여기
<div>
<h2>Free Webtoon</h2>
<ul>{/* 반복문 : li 대해서 */}
{webtoon.map((item) => (
<li className="item" key={item.id}>
<a href={item.link}>
<img src={item.img} />
<span className="tit">제목 {item.name}</span>
</a>
{/* item.isUpdate 있으면 span 태그 실행 */}
{item.isUpdate && <span className="tag">N</span>}
</li>
))}
</ul>
</div>
);
}
export default WebtoonExam;
IWebtoon.ts
export default interface IWebtoon {
id: number,
name: string,
link: string,
img: string,
isUpdate: boolean,
}
결과

'HTML > React' 카테고리의 다른 글
[React] json 서버 사용법 (0) | 2023.09.04 |
---|---|
[React] (0) | 2023.09.04 |
[React]backtick, nullish, dataset, encode, decode, formData, function, structure, promise then, catch, boot strap, layout (0) | 2023.08.28 |
[React] 노드 설치법 , 화살표 함수, 내장함수(spread, foreach, map, filter) (0) | 2023.08.28 |