👥Club/☁️9oormthon univ☁️
TypeScript
비엔 Vien
2025. 5. 18. 11:10
TypeScript
: 자바스크립트를 기반으로 하되 몇가지 기능(정적 타입)을 더 추가함
ㄴ 경고해주는 기능 같은것....\\
ㄴㄴ (타입표기 ':타입' 식으로 )
r기본형 타입
let age: number;
let name: string;
...
좀 더 복잡한 친구들
let hobbies: string[];
let person: {
name: string;
age: number;
}
타입 추론 - 불필요하게 타입을 추론할 필요는 없다
let course = 'aaa';
굳이 let course :String = 'aaa'; 할 필요 X
유니온 타입
let a: string | string[];
타입 별칭⭐️
type Person = {
name: string;
age: number;
};
let person: Person;
let people: Person[];
함수
function(a:neber, b:number){
return a+b;
}
//but 필요한게 아닌 경우 반환값 타입은 굳이 쓰지 말기
function(a:neber, b:number) :number{
return a+b;
}
function print(value:any){
console.log(value);
}
제네릭
function insertAtBeginning<T>(array: T[], value: T) {
const newArray = [value, ...array];
return newArray;
}
const demoArray = [1, 2, 3];
const updatedArray = insertAtBeginning(demoArray, -1); // [-1, 1, 2, 3]
const stringArray = insertAtBeginning(['b', 'c'], 'a'); // ['a', 'b', 'c']
보통 함수나 클래스에서 다양한 타입을 다루고 싶을 때 모든 타입에 대응하려고 any를 쓰면 타입 안정성이 깨짐..
>> 제네릭을 쓰면 타입을 나중에 결정하되, 안전하게 사용할 수 있음
//App.jsx
import React from 'react';
const Todos: React.FC<{ items: string[] }> = (props) => {
return (
<ul>
{props.items.map(item => <li key={item}>{item}</li>)}
</ul>
);
};
export default Todos;
//Todos.tsx
import React from 'react';
//props로 items라는 string 배열을 받아옴
//제네릭으로 props 타입을 지정
const Todos: React.FC<{ items: string[] }> = (props) => {
return (
<ul>
{props.items.map(item => <li key={item}>{item}</li>)}
</ul>
);
};
export default Todos;
typescript는 class 에 추가할 속성이나 프로퍼티가 잇을 경우 생성자를 통해 추가할 필요 없음
//Todo.tsx
import React from "react";
import Todo from '../models/todos';
const Todos: React.FC<{ items: Todo[] }> = (props) => {
return (
<ul>
{props.items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
};
export default Todos;
//App.tsx
import Todos from './components/Todos';
import Todo from './models/todos';
function App() {
const todos = [new Todo('Learn React'), new Todo('Learn TypeScript')];
return (
<div>
<Todos items={todos} />
</div>
);
}
export default App;
//todos.ts
class Todo{
id: string;
text: string;
//생성자에서 todoText를 받아 text 속성에 저장하고, id는 현재 시간을 기반으로 자동 생성
//TypeScript에서는 이렇게 생성자 내부에서 프로퍼티를 초기화해주면 따로 this.text = ...처럼 하지 않고도 자동으로 클래스에 속성 추가가 됨
constructor(todoText: string) {
this.text = todoText;
this.id = new Date().toISOString(); // 고유한 ID 자동 생성
}
}
export default Todo;
//TodoItem.tsx
//props로 text만 전달받고, 내부에서는 해당 텍스트만 렌더링
const TodoItem: React.FC<{text: string }> = (props) => {
return <li>{props.text}</li>
};
export default TodoItem;
//Todo.tsx
import React from "react";
import TodoItem from './TodoItem';
import Todo from '../models/todos';
const Todos: React.FC<{ items: Todo[] }> = (props) => {
return (
<ul>
{props.items.map((item) => (
// 컴포넌트 별도로 분리하여,,
<TodoItem key={item.id} text={item.text}/>
))}
</ul>
);
};
export default Todos;
사용자에게 입력창 제공
//NewTodos.tsx
const NewTodo = () => {
const submitHandler = (event: React.FormEvent) => {
event.preventDefault();
};
return (
<form onSubmit={submitHandler}>
<label htmlFor="text">Todo text</label>
<input type="text" id="text" />
<button>Add Todo</button>
</form>
);
};
export default NewTodo;
타입스크립트에서 ref 사용시 더 많은 정보 알려줘야 함
(해당 레퍼런스에 저장 될 데이터가 어떤 타입인지 알려줘야 함
/?NewTodo.tsx
import { useRef } from "react";
const NewTodo = () => {
const todoTextInputRef = useRef<HTMLInputElement>(null);
const submitHandler = (event: React.FormEvent) => {
event.preventDefault();
const enteredText = todoTextInputRef.current!.value;
if (enteredText?.trim().length === 0) {
// 예시: 값이 비었을 경우 처리
return;
}
};
return (
<form onSubmit={submitHandler}>
<label htmlFor="text">Todo text</label>
<input type="text" id="text" ref={todoTextInputRef} />
<button>Add Todo</button>
</form>
);
};
export default NewTodo;
//onAddTodo가 함수 타입이어야 한다는 제네릭...
//NewTodo.tsx
import { useRef } from "react";
//onAddTodo가 함수 타입이어야 한다는 제네릭...
const NewTodo: React.FC<{onAddTodo: (text: string) => void}> = (props) => {
const todoTextInputRef = useRef<HTMLInputElement>(null);
const submitHandler = (event: React.FormEvent) => {
event.preventDefault();
const enteredText = todoTextInputRef.current!.value;
if (enteredText?.trim().length === 0) {
// 예시: 값이 비었을 경우 처리
return;
}
props.onAddTodo(enteredText);
};
return (
<form onSubmit={submitHandler}>
<label htmlFor="text">Todo text</label>
<input type="text" id="text" ref={todoTextInputRef} />
<button>Add Todo</button>
</form>
);
};
export default NewTodo;
//App.tsx
import Todos from "./components/Todos";
import Todo from "./models/todos";
import NewTodo from "./components/NewTodos";
function App() {
const todos = [new Todo("Learn React"), new Todo("Learn TypeScript")];
const addTodoHandler = (todoText: string) => {
};
return (
<div>
<NewTodo onAddTodo={addTodoHandler}/>
<Todos items={todos} />
</div>
);
}
export default App;
state 업데이트
import {useState} from 'react';
import Todos from "./components/Todos";
import Todo from "./models/todos";
import NewTodo from "./components/NewTodos";
function App() {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodoHandler = (todoText: string) => {
const newTodo = new Todo(todoText);
//상태 업데이트
//newTodo를 마지막에 추가한 새로운 배열을 만들어서 상태 업데이트
setTodos((prevTodos) => {
return prevTodos.concat(newTodo);
});
};
return (
<div>
<NewTodo onAddTodo={addTodoHandler}/>
<Todos items={todos} />
</div>
);
}
export default App;
css 추가하기.. 그냥
클릭을 통한 삭제
import { useState } from "react";
import Todos from "./components/Todos";
import Todo from "./models/todos";
import NewTodo from "./components/NewTodos";
function App() {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodoHandler = (todoText: string) => {
const newTodo = new Todo(todoText);
setTodos((prevTodos) => {
return prevTodos.concat(newTodo);
});
};
const removeTodoHandler = (todoId: string) => {
setTodos((prevTodos) => {
return prevTodos.filter((todo) => todo.id !== todoId);
});
};
return (
<div>
<NewTodo onAddTodo={addTodoHandler} />
<Todos items={todos} onRemoveTodo={removeTodoHandler} />
</div>
);
}
export default App;
.bind() : 실행할 함수 미리 정의 가능
import React from "react";
import TodoItem from "./TodoItem";
import Todo from "../models/todos";
import classes from "./Todos.module.css";
const Todos: React.FC<{ items: Todo[]; onRemoveTodo: (id: string) => void }> = (
props
) => {
return (
<ul className ={classes.todos}>
{props.items.map((item) => (
<TodoItem
key={item.id}
text={item.text}
onRemoveTodo={props.onRemoveTodo.bind(null, item.id)}
/>
))}
</ul>
);
};
export default Todos;
import classes from './TodoItem.module.css';
const TodoItem: React.FC<{text: string; onRemoveTodo: (event: React.MouseEvent) => void }> = (props) => {
return <li className={classes.item} onClick={props.onRemoveTodo}>{props.text}</li>
};
export default TodoItem;