HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mini Project</title>
</head>
<body>
<ul id="todoList">
</ul>
<form id="todoform" action="">
<input id="todoinput" type="text" placeholder="enter a todo" />
<button id="btn" type="submit">Click Me</button>
</form>
<script src="dist/index.js"></script>
</body>
</html>
TS
interface Todo {
text: string,
completed: boolean
}
const btn = document.getElementById("btn") as HTMLButtonElement
const input = document.getElementById("todoinput") as HTMLInputElement
const form = document.querySelector("#todoform") as HTMLFormElement
const list = document.querySelector("#todoList") as HTMLUListElement
const readTodos = (): Todo[] => {
const todosJSON = localStorage.getItem("todos")
if (todosJSON === null) return []
return JSON.parse(todosJSON)
}
const createTodo = (todo: Todo) => {
const newLI = document.createElement("li")
const checkbox = document.createElement("input")
checkbox.type = "checkbox"
checkbox.checked = todo.completed
checkbox.addEventListener("change", () => {
todo.completed = checkbox.checked
saveTodos()
})
newLI.append(todo.text)
newLI.append(checkbox)
list?.append(newLI)
}
const saveTodos = () => {
localStorage.setItem("todos", JSON.stringify(todos))
}
const handleSubmit = (e: SubmitEvent) => {
e.preventDefault()
const newTodo: Todo = {
text: input.value,
completed: false,
}
createTodo(newTodo)
todos.push(newTodo)
saveTodos()
input.value = ""
}
const todos: Todo[] = readTodos()
todos.forEach(createTodo)
form.addEventListener("submit", handleSubmit)
정리
interface 정의 (interface는 추상화다)
- 위 코드에서는 Todo 목록에 사용할 인터페이스를 정의하는 작업을 했다.
- todolist의 text(string) 부분과 완료했는지 여부를 따지는 completed(boolean)라는 부분을
todo로 추상화한 것이라고 볼 수 있다. - 그러므로, interface를 선언할 때는 컴퓨터 자료형들로 구성된 데이터를 상위단계로 추상화한다는 개념으로 접근해야 한다. (추상화 -> 현실의 것들, 컴퓨터의 개념을 현실에서 쓰이는 것으로 바꾸는 행위)
- 이는 객체지향 프로그래밍과도 어느정도 상통할 부분이겠다.
타입 단언 (Type Assertion)
- 타입스크립트는 자바스크립트의 타입을 정의해주는 언어이다.
- 자바스크립트가 어느정도 자유로운 언어이므로, 타입스크립트도 자바스크립트의 타입 정의에 있어 불확실한 경우가 많다.
- 이 때, 개발자인 우리가 타입스크립트가 완벽하게 타입 정의를 해줄 수 없다는 것을 자각하고, 특별한 상황에 있어서는 타입을 단언해주어야 한다.
- 위의 경우, getElementById나 querySelector는 HTMLElement를 반환하거나 null을 반환하는 메서드이다.
- 따라서 위의 const { btn, input, form, list } 의 경우에는 Element나 null 둘 중 하나를 받는다고 생각할 것이다.
- 하지만 엄밀히 따지자면 button은 HTMLElement가 아니고, HTMLElement를 확장한 HTMLButtonElement 프로토타입을 따른다.
- input도 HTMLElement를 확장한 HTMLInputElement 프로토타입을 따르며, form도 HTMLFormElement를 따르고, list도 HTMLUListElement를 따른다.
- 각 프로토타입마다 프로퍼티나 메서드가 다르기 때문에 타입을 명확히 정의해주어야 하며
- 우리는 as 뒤에 타입을 단언해줌으로써 위의 문제를 해결할 수 있다.
'Typescript' 카테고리의 다른 글
함수 표현식에 타입 적용하기 (0) | 2023.07.31 |
---|---|
타입 단언과 타입 선언 사용 시기 (0) | 2023.07.27 |
(TS) 타입 단언 (Type Assertion) (0) | 2023.03.11 |
(TS) non null / optional chaning (0) | 2023.03.11 |
(TS) tsconfig / lib (0) | 2023.03.11 |