FrontEnd/React

[ TypeScript ] 기초

ChatjihoiPT 2025. 4. 11. 21:39

Typescript란?

type이 있는 자바스크립트로

정적 타입을 제공하며 개발 시 타입 오류를 보여줌으로써 추후 개발 시 오류 예방할 수 있음

let name = "챗지회피티";  // JS에서는 문자열인지 검사 안 함
let age: number = 23;  // TS에서는 타입 지정 시 그 타입만 가능

 

Typescript 분류내용 ]

타입 선언 type, interface, enum 등
타입 조합 유니언(`
타입 별칭 이름 붙여서 재사용
타입 예시 문자열, 숫자, 객체, 배열, 함수 등
특수 타입 children, ReactNode, CSSProperties
비교 interface vs type & 명확히 구분

 


1. React에서 사용하는 Event

React Event는 React에서 사용하는 이벤트 처리 시스템
이는 브라우저의 DOM 이벤트를 추상화한 것으로, 일관된 방식으로 이벤트를 처리할 수 있도록 해줌


1.1 ReactEvent 

HTML 요소 타입스크립트 이벤트 타입 비고
<input> React.ChangeEvent<HTMLInputElement> text, password, checkbox, radio
<textarea> React.ChangeEvent<HTMLTextAreaElement>  
<select> React.ChangeEvent<HTMLSelectElement>  
<button> React.ChangeEvent<HTMLButtonElement>  
<div> React.ChangeEvent<HTMLDivElement>  
<form> React.ChangeEvent<HTMLFormElement> <form onSubmit={}>

 


1.2  SyntheticEvent  개념

브라우저의 **기본 DOM 이벤트(native event)**를 감싼 React 고유의 이벤트 객체

- 메모리 최적화를 위해 풀(Pool)을 재사용함

event.target → 실제 DOM 요소
event.currentTarget → 이벤트 리스너가 부착된 요소
function handleClick(event: React.SyntheticEvent) {
  console.log(event.type); // 클릭, 입력 등 이벤트 종류
}

2. Type 선언 ( Type 정의 방식 )

변수, 함수, 객체 등이 어떤 데이터 타입을 갖는지 명확히 지정하는 것


2.1 type (타입 별칭)

타입을 선언하는 기능으로 컴포넌트의 props에 타입을 지정 가능

 type은 타입 별칭(Type Alias)를 만들때 사용됨

- 기본 타입, 유니언(Union), 인터섹션(Intersection), 리터럴 타입 등을 정의할 때 사용
- interface보다 더 다양한 타입 정의가 가능

 

-> 구조 분해 할당 사용

-> BUT 구조 분해 할당만 쓰는 것 보다는 type이나 interface로 지정해줘야 타입 안정성이 높아지고, 확장성 면에서 권장됨

 

구조 분해 할당]

import React from "react";

const MyButton = ({ title }: { title: string }) => {  // props(객체): type
  return <button>{title}</button>;
};

export default MyButton;

 

type와 Interface]

interface MyButtonprops {
  title: string;
  disabled: boolean;
}

const MyButton = ({ title, disabled }: MyButtonprops) => {
  return <button disabled={disabled}>{title}</button>;
};

export default MyButton;

2.2 interface (인터페이스)

  • 클래스를 정의하거나 함수의 매개변수, 리턴값 등의 객체 구조를 명확하게 함
  • 같은 이름의 인터페이스는 자동으로 병합(Merge)될 수 있음
  • 유니언, 함수, 리터럴(타입 조합) 등의 복합 타입
import {useReducer} from 'react';

interface State {
   count: number
};

type CounterAction =
  | { type: "reset" }
  | { type: "setCount"; value: State["count"] }

const initialState: State = { count: 0 };

function stateReducer(state: State, action: CounterAction): State {
                                    // action 뒤에 union
  switch (action.type) {
    case "reset":
      return initialState;
    case "setCount":
      return { ...state, count: action.value };
    default:
      throw new Error("Unknown action");
  }
}

export default function App() {
  const [state, dispatch] = useReducer(stateReducer, initialState);

  const addFive = () => dispatch({ type: "setCount", value: state.count + 5 });
  const reset = () => dispatch({ type: "reset" });

  return (
    <div>
      <h1>Welcome to my counter</h1>

      <p>Count: {state.count}</p>
      <button onClick={addFive}>Add 5</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

2.3  enum (열거형)

상수들의 집합을 정의할 때 사용함

  • 코드의 가독성과 유지보수성을 높임
  • 기본적으로 숫자 값이 할당되지만 문자열 등도 가능
import React from 'react';
interface TodoItem {
  id: Number;
  text: string;
  completed: boolean;
}
enum Command {
  ADD,
  TOGGLE,
  REMOVE,
}
 
type Action = 
  | { type: Command.ADD; text: string } //union 설정
  | { type: Command.TOGGLE; id: string }
  | { type: Command.REMOVE; id: string };
  
const Todo = () => {
  return (
    <div>
      
    </div>
  );
};

export default Todo;
return state.map((todo: TodoItem) => { });  todo의 타입을 TodoItem으로 선언해도 되지만
    // reducer = (state: TodoItem[], actionL: Action) ==> 을 통해서 
    // state.map((todo)=>{}); 하면 todo는 TodoItem으로 추론할 수 있으므로 선언 안 해도 된다.

 

 


3. Type 조합

여러 개의 타입을 하나로 합치는 것


3.1 Union (유니언)

타입 연산자(조합)로 조건 중 하나만 만족하면 됨

(A \| B)
type ID = string | number;

let userId: ID = "abc123";
userId = 456;

3.2 Intersection (인터섹션)

타입 연산자(조합)로 모든 조건을 만족해야 됨

(A & B)
type Name = { name: string };
type Age = { age: number };
type Person = Name & Age;

const me: Person = { name: "도희", age: 25 };

(A & B)


4. Type Keyword

TypeScript에서 새로운 타입에 이름을 붙여주는 키워드입니다.
복잡한 타입을 **간단하게 별칭(alias)**으로 만들어 재사용하거나 조합할때 사용

CSSProperties style={{ ... }}에 들어갈 객체의 타입 { color: "red", fontSize: "12px" }
ReactNode 컴포넌트의 자식(children) 타입으로 사용 "문자", 123, <div />, null 등

4.1 ReactNode

children ]

컴포넌트 내부에 포함되는 자식 요소

  • React의 component에서 사용됨
  • children은 React 내장 타입인 ReactNode로 타입 지정
import MyButton from "./MyButton";

function App() {
  return (
    <div className="App">
      <MyButton title="확인"></MyButton>
                      // props 그리고 >children<
                      // childeren 선언 후 사용가능
    </div>
  );
}

export default App;
interface FromData {
  username: string;
  message: string;
}

const EventHandle = () => {
  const [data, setData] = useState<FormData>()  // type을 FormData로 설정
  return ()

4.2 CSSProperties

React에서 스타일 객체의 타입을 정의한 인터페이스

- import하면 style={{ ... }} 안에 쓰는 속성들을 자동완성 + 타입 체크

Style]

import React, { CSSProperties } from 'react';

const boxStyle: CSSProperties = {
  backgroundColor: 'skyblue',
  color: 'white',
  fontSize: '20px',
  padding: '10px',
  borderRadius: '8px'
};

function StyledBox() {
  return <div style={boxStyle}>이건 스타일이 적용된 박스입니다</div>;
}

export default StyledBox;

5. Type  사용 예시 

5.1 객체

 

  • 객체 구조를 정의할 때 자주 사용
  • 선택적 속성은 ? 사용

 

type User = {
  name: string;
  age: number;
  isAdmin?: boolean; // optional
};

const user1: User = {
  name: "도희",
  age: 25
};

5.2 배열

  • 배열 타입은 string[] 또는 Array<string> 형태 모두 가능
type StringArray = string[];
type NumberList = Array<number>;

const names: StringArray = ["Alice", "Bob"];
const scores: NumberList = [100, 90, 85];

5.3 함수

 

  • 함수의 매개변수 타입과 반환 타입을 모두 지정 가능
  • 콜백 함수, 고차 함수에도 유용
type Add = (a: number, b: number) => number;

const add: Add = (x, y) => x + y;

 


5.4 리터럴

 

 

 

  • 문자열, 숫자 등의 고정된 값만 허용할 수 있게 만듦
  • 버튼 상태, API 상태값 등에 자주 활용
type Direction = "left" | "right" | "up" | "down";

let move: Direction = "left"; // ✅
move = "up";                  // ✅
// move = "forward";         // ❌ 에러!

 


6. Interface(타입 선언) VS Intersection(타입 조합) 비교

6.1 Interface

객체의 구조를 정의할 때 사용(객체 지향 스타일)

- extends를 이용해 상속하고 확장 가능

- 구조 설계에 적합하고, 선언 병합도 가능하나 객체만 적용 가능

interface Person {
  name: string;
}

interface Employee extends Person {
  employeeId: number;
}

const worker: Employee = {
  name: "도희",
  employeeId: 1234
};

 


6.2 Intersection (&)

여러 타입을 합쳐서 하나의 타입으로 만드는 연산자

- 객체뿐 아니라 유니언 타입, 기본 탕딥, 조건 타입 등에도 사용 가능

type Person = {
  name: string;
};

type Employee = {
  employeeId: number;
};

type Worker = Person & Employee;

const worker: Worker = {
  name: "도희",
  employeeId: 1234
};