091
[TS/React] TypeScript 본문
1. TypeScript
- 타입 시스템이란 타입과 관련해서 지켜야 하는 규칙들을 모아둔 체계입니다. 변수의 타입을 결정하는 시기에 따라서 정적 타입과 동적 타입으로 나뉘고 정적 타입 언어로는 C, Java 등이, 동적 타입 언어로는 Python, JavaScript가 있습니다.
- 이런 동적 타입 언어인 JavaScript를 타입을 더 안전하게 사용할 수 있는 기능을 추가한 언어가 바로 TypeScript이며, Microsoft에서 개발/유지하고 있는 오픈 소스 프로그래밍 언어입니다. 이때 TypeScript 코드는 컴파일러(tsc)를 사용하여 JS로 변환한 후 실행됩니다.
// JavaScript
let a = 1;
let b = 2;
// TypeScript
let a:number = 1;
let b:number = 2;
console.log(a + b)
- 프로젝트 시작 방법
(1) 새 프로젝트(vite)
npm create vite@latest ts-app
(2)기존 프로젝트에 추가하는 방법
npm i typescript @types/node @types/react @types/react-dom
1️⃣typescript를 설치해주고, 기존에 있던 라이브러리를 타입스크립트에서 사용하기 위해 @types를 붙여 타입스크립트 라이브러리를 설치합니다.
npx tsc --init
2️⃣tsconfig.json 파일 생성해주는 명령어로, TypeScript 컴파일러 설정 파일을 생성해줍니다.
3️⃣ package.json 파일의 build 명령어에 tsc 컴파일 항목을 추가해줍니다.

4️⃣ 그외에 이제 필요한 순서대로 파일의 확장자를 tsx로 바꾸고 내부 변수들의 타입정보를 설정해줘야합니다.
5️⃣ npm run build를 통해 오류를 찾아 수정합니다.
- TypeScript의 기본적인 타입종류
| type | 설명 |
| string | 문자열 |
| number | 모든 수(최대 2의 53승) |
| boolean | true 또는 false |
| undefined | undefined |
| null | null |
| any | 뭐든지 가능(사용 권장하지 않음) |
| void | 함수에 반환 값을 설정할 수 없는 타입 |
| object | 객체 |
| type[] | 배열 |
| [type, type, ...] | 튜플 |
let a: string = '문자열';
let b: number = 123;
• 변수 표기법: 타입은 무조건 소문자로 작성하며, 변수 오른쪽에 콜론 기호 뒤에 타입을 작성합니다.
function add(x: number, y: number): number {
return x+y;
}
const add = (x: number, y: number): number => {
return x+y;
}
• 함수 표기법: 매개변수 옆에 타입을 적고, 매개변수 닫는 괄호 옆에 리턴 값의 타입을 작성합니다.
let obj: {a: number, b: string} = {
a: 1, b: 'test'
}
• 객체 표기법: key에 해당하는 value의 타입을 작성해줍니다.
let arr1: string[] = ['a', 'b', 'c'];
let arr2: number[] = [1, 2, 3];
• 배열 표기법: 배열의 요소 타입을 적고 타입[] 형태로 작성해줍니다.
let tuple: [number, number, string] = [123, 456, "one"];
• 튜플 표기법: 타입과 튜플 요소의 개수가 같아야만 성립하며, 각 요소의 타입이 다를 수 있기 때문에 각 요소의 타입을 정해줘야합니다.
const x: number = 5;
const b: true = true; //true 리터럴(오직 true만 가능함)
const f: boolean = true; // 타입 범위 최소화 요구
• 고정된 값 표기법: const를 사용한 변수를 선언하면 해당 변수의 값은 절대로 변하지 않습니다.
type AddType = (a: number, b: number) => number;
const add: AddType = (a, b) => a + b;
type Operation = {
(a: number, b: number): number;
};
const add2: Operation = (a, b) => a + b;
const sub2: Operation = (a, b) => a - b;
const multiply2: Operation = (a, b) => a * b;
const divide2: Operation = (a, b) => a / b;
• 타입 표기법: 함수 타입을 타입 별칭과 함께 정의할 때 사용됩니다.
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "이정환",
age: 27,
};
person.name = '홍길동';
• 인터페이스 표기법: 타입 별칭과 동일하게 타입에 이름을 지어주는 또 다른 문법입니다.
function func<T>(value: T): T {
return value;
}
let num = func(10);
let arr = func<[number, number, number]>([1, 2, 3]);
• 제네릭 표기법: 제네릭이란 함수나 인터페이스, 타입 별칭, 클래스 등을 다양한 타입과 함께 동작하도록 만들어주는 기능으로, 함수 이름 뒤에 꺽쇠를 열고 타입을 담는 변수인 T를 선언합니다.
const [count, setCount] = useState<number>(0);
type Status = "idle" | "loading" | "success" | "error";
const [status, setStatus] = useState<Status>("idle");// 유니언 타입
• useState 표기법: 초기 state로 전달된 값을 사용하여 추론된 값의 타입을 결정하는데, 타입스크립트에서는 이를 프로그래머가 명시적으로 설정했습니다.
export default function MyAppTs() {
const [value, setValue] = useState("Init string"); //추론으로 명시X
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.currentTarget.value);
}
function handleClick(event: React.MouseEvent<HTMLElement>) {
alert('click');
}
return (
<div>
<input value={value} onChange={handleChange} />
<p>Value: {value}</p>
<button onClick={handleClick}>click</button>
</div>
);
}
• React DOM 이벤트 표기법: DOM 이벤트 타입을 명시적으로 설정해줘야합니다. 이때 내부에서 target 대신에 currentTarget을 써줘야합니다.
-> React.ChangeEvent<HTMLInputElement>: 값이 바뀔 때 발생하는 이벤트 중 <input> 태그에서 발생했다는 의미입니다.
-> React.MouseEvent<HTMLElement>: 마우스 클릭으로 발생하는 이벤트 중 일반적인 HTML 요소에서 발생했다는 의미입니다.
- 실습예시: 컴포넌트 props에 타입을 지정함
function MyButton({ id, title }) { //js
return (
<div>
<button>
{id} {title}
</button>
</div>
);
}
function MyButton({ id, title }:{id: number, title: string}) { //ts+인라인 타입 지정
return (
<div>
<button>
{id} {title}
</button>
</div>
);
}
interface MyButtonProps {
id: number;
title: string;
}
function MyButton({ id, title }: MyButtonProps) { //ts+interface 타입 지정
return (
<div>
<button>
{id} {title}
</button>
</div>
);
}
- 실습: TodoList.tsx
import { useState, type ChangeEvent } from "react";
type Todo = {
id: Date;
text: string;
checked: boolean;
};
export default function TodoList() {
const [todos, setTodos] = useState<Todo[]>([]);
const [input, setInput] = useState<string>("");
const addTodo = (): void => {
if (input === "") return;
const todo_item: Todo = {
id: new Date(),
text: input,
checked: false,
};
setTodos([...todos, todo_item]);
setInput("");
};
const deleteTodo = (id: Date): void => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
setInput(e.currentTarget.value);
};
return (
<div style={{ margin: 10 }}>
<h2>할 일 목록</h2>
<div>
<input type="text" value={input} onChange={handleInputChange} />
<button onClick={addTodo}>추가</button>
</div>
{todos.map((todo) => (
<div key={todo.id.toString()}>
<span>{todo.text}</span>
<button onClick={() => deleteTodo(todo.id)}>삭제</button>
</div>
))}
</div>
);
}
-> type ChangeEvent: 타입만을 가져온다는 뜻으로, type 키워드를 붙여서 이건 타입이라 JS 변환 후 사라진다는 것을 명시합니다.
'Programming Language > JavaScript&TypeScript' 카테고리의 다른 글
| [JS/React] CSS 문법(선택자,레이아웃), Styled-Component (0) | 2026.06.08 |
|---|---|
| [JS/React] Shared State, Context (0) | 2026.06.06 |
| [JS/React] REST (0) | 2026.06.06 |
| [JS/React] 리액트 라우터(React Router) (0) | 2026.05.24 |
| [JS/React] 리스트와 키, 입력 폼 (0) | 2026.04.18 |