- 타입스크립트 기초 -( 1 )2025년 03월 06일
- redpome
- 작성자
- 2025.03.06.:11
Vite을 통해 React+Typescript 조합으로 타입스크립트 기초를 배우자
타입 명시
import Name from "./components/Name.tsx"; const App = () => { return ( <div> <Name name="Song" /> </div> ); }; export default App;
처음 만들 때 생성되는 App 컴포넌트에서 위와 같이 코드를 수정했다. 이때 Name이라는 컴포넌트에 name="string"이라고 적어 마치 직접 name의 값을 넘겨주는 것처럼 보이는데 보이는 것처럼 Name이라는 컴포넌트에 해당 값을 넘겨주고 있는것이다.
type PropTypes = { name: string; }; const Name = ({ name }: PropTypes) => { return ( <div> <h2>Hello,{name}</h2> </div> ); }; export default Name;
Name이라는 컴포넌트에는 type PropTypes에서 name:string으로 지정했다.
Name은 문자열의 name이라는 props를 받아야하는 것을 명시한 것으로 부모 컴포넌트인 App에서는 name에 값을 넣어 사용한다.
아니면 다음과 같이 처음부터 Name에서 name의 값을 넘겨주는 방법도 있다.
const Name = ({ name = "Song" }: PropTypes) => { return <h2>Hello, {name}</h2>; };
이처럼 타입스크립트는 선언 시에 타입이 고정된다. 다음의 예시를 보자
const add = (a: number, b: number): number => { return a + b; }; const sum: string = add(1, 2); console.log(sum);
add라는 함수는 number 타입의 a,b를 받고 결과도 number를 반환하는 것을 명시한다. 그런데 sum이라는 변수의 타입을 string을 명시하고 number를 반환하는 add(1,2)를 할당했다, 이때에는 오류가 발생한다. 참고로 호이스팅 문제를 피하기 위해 함수형으로 쓴다면 다음과 같이 쓸 수 있다.
function add(a: number, b: number): number { return a + b; } const sum: number = add(1, 2); console.log(sum);
CRUD: 투두리스트
CRUD를 타입스크립트로 만들어본다, 우선 App.tsx와 todo.ts로 구성되어있다.
todo.ts에는 다음과 같이 되어있다.export type Todo = { id: string; title: string; completed: boolean; }; export async function getTodos() { const response = await fetch("http://localhost:5000/todos"); const data: Todo[] = await response.json(); return data; } getTodos().then((response) => console.log(response[0]));
Todo라는 타입을 정의하였고, json-server를 통해 db.json을 관리하므로 getTodos에서 데이터를 가져온다.
import "./App.css"; import { type Todo } from "./components/todos"; function App() { return <TodoList todoList={[]}></TodoList>; } function TodoList({ todoList }: { todoList: Todo[] }) { return ( <> {todoList.map((todo) => ( <TodoItem {...todo} /> ))} </> ); } function TodoItem({ id, title, completed }: Todo) { return ( <div> <div>id:{id}</div> <div>title:{title}</div> <div>completed:{completed}</div> </div> ); } export default App;
App,TodoList,TodoItem의 컴포넌트들로 구성되어있다. Props를 전달하는 방식에서 차이점이라면 넘겨주는 Props의 자료형을 명시해준 것이다.
... function App() { return <TodoList todoList={[]}></TodoList>; ... function TodoList({ todoList }: { todoList: Todo[] }) { ... {todoList.map((todo) => ( <TodoItem {...todo} /> ... function TodoItem({ id, title, completed }: Todo) { ... <div>id:{id}</div> <div>title:{title}</div> <div>completed:{completed}</div> ...
TodoItem은 Todo라는 타입을 통해 받는 Props의 타입을 명시하고 있다. TodoList 컴포넌트에서는 todoList를 Props로 받고 Todo라는 타입을 명시함과 동시에 배열에 받는다는 뜻이다. Spread Operator를 통해 todo의 속성까지 TodoItem에서 지정한 Todo타입을 그대로 받는다.
const [todoList, setTodoList] = useState(); useEffect(() => { getTodos().then((data) => setTodoList(data)); }, []);
현재 위의 코드에서 setTodoList(data)에서 오류가 발생한다, useState에 아무런 초기값이 없으며 어떤 타입을 받을 지도 명시하지 않았다.
const [todoList, setTodoList] = useState<Todo[]>([]); useEffect(() => { getTodos().then((data) => setTodoList(data)); }, []);
초기값으로 빈 배열을 넣어주고 Todo[]라는 타입을 명시하여 어떤 타입의 값을 받는지 명시했다, undefined일 수 있는 값을 이제 안 받아도 된다.
실행 화면 현재 실행 시 db.json의 값을 잘 읽어오고 있는 것을 확인할 수 있다.
Create
const handleTitleChange = (e) => { setTitle(e.target.value); }; return ( <> <TodoList todoList={todoList} /> <input type="text" onChange={}></input> </> );
자연스레 작성하는 형식이지만 e의 타입이 명시되지 않았다.
const [title, setTitle] = useState(""); const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => { setTitle(e.target.value); }; return ( <> <TodoList todoList={todoList} /> <input type="text" value={title} onChange={handleTitleChange} /> </> ); }
위와 같이 e의 타입을 위해 onChange에서 e를 handleTitleChange 인자로 넘겨주는 방식을 취하면 마우스를 e에 올렸을때 어떤 타입으로 명시해야하는지 툴팁이 나온다. 그걸 갖다쓰면 된다.
... const [todoList, setTodoList] = useState<Todo[]>([]); useEffect(() => { getTodos().then((data) => setTodoList(data)); }, []); const [title, setTitle] = useState(""); const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => { setTitle(e.target.value); }; const handleAddTodo = async () => { const newTodo: Todo = { id: crypto.randomUUID(), title, completed: false, }; await fetch("http://localhost:5000/todos", { method: "POST", body: JSON.stringify(newTodo), }); setTodoList((prev) => [...prev, newTodo]); }; ... <input type="text" value={title} onChange={handleTitleChange} /> <button onClick={handleAddTodo}>입력</button> </> );
fetch를 이용해 POST 요청을 보내 서버에 데이터를 저장한 후, setTodoList를 이용해 기존 상태에 새로운 Todo를 추가했다.
여기까지는 기존의 했던 방식과 똑같다.
너무 길어졌으니 일단 여기서 마무리
'타입스크립트' 카테고리의 다른 글
타입 스크립트 기초 - (2) (0) 2025.03.07 다음글이전글이전 글이 없습니다.댓글