From 02636175c9f369419866d0ce0a47dcbbd5330760 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 11:48:42 +0900
Subject: [PATCH 01/12] =?UTF-8?q?5=EC=A3=BC=EC=B0=A8-=ED=94=84=EB=A1=9C?=
=?UTF-8?q?=EC=A0=9D=ED=8A=B8=20TS=20=EA=B8=B0=EB=B3=B8=20=EB=B3=80?=
=?UTF-8?q?=ED=99=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../projects/FEDC5-3_VanillaJS_1/.gitignore | 24 +
.../projects/FEDC5-3_VanillaJS_1/index.html | 13 +
.../FEDC5-3_VanillaJS_1/package-lock.json | 732 ++++++++++++++++++
.../projects/FEDC5-3_VanillaJS_1/package.json | 15 +
.../FEDC5-3_VanillaJS_1/public/vite.svg | 1 +
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 71 ++
.../src/components/Header.ts | 21 +
.../src/components/TodoCount.ts | 40 +
.../src/components/TodoForm.ts | 45 ++
.../src/components/TodoItem.ts | 41 +
.../src/components/TodoList.ts | 45 ++
.../FEDC5-3_VanillaJS_1/src/counter.ts | 9 +
.../projects/FEDC5-3_VanillaJS_1/src/main.ts | 11 +
.../FEDC5-3_VanillaJS_1/src/typescript.svg | 1 +
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 28 +
.../src/utils/validateState.ts | 45 ++
.../FEDC5-3_VanillaJS_1/src/vite-env.d.ts | 1 +
.../FEDC5-3_VanillaJS_1/tsconfig.json | 23 +
18 files changed, 1166 insertions(+)
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/.gitignore
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/index.html
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/package-lock.json
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/package.json
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/public/vite.svg
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/main.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/typescript.svg
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/vite-env.d.ts
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/tsconfig.json
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/.gitignore b/yongjae/projects/FEDC5-3_VanillaJS_1/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/index.html b/yongjae/projects/FEDC5-3_VanillaJS_1/index.html
new file mode 100644
index 0000000..3f32d0c
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ TS Todo
+
+
+
+
+
+
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/package-lock.json b/yongjae/projects/FEDC5-3_VanillaJS_1/package-lock.json
new file mode 100644
index 0000000..cffe8f2
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/package-lock.json
@@ -0,0 +1,732 @@
+{
+ "name": "fedc5-3-vanillajs-1",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "fedc5-3-vanillajs-1",
+ "version": "0.0.0",
+ "devDependencies": {
+ "typescript": "^5.2.2",
+ "vite": "^5.0.0"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz",
+ "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz",
+ "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz",
+ "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz",
+ "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz",
+ "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz",
+ "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz",
+ "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz",
+ "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz",
+ "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz",
+ "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz",
+ "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz",
+ "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz",
+ "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz",
+ "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz",
+ "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz",
+ "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz",
+ "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz",
+ "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz",
+ "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz",
+ "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz",
+ "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz",
+ "integrity": "sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz",
+ "integrity": "sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz",
+ "integrity": "sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz",
+ "integrity": "sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz",
+ "integrity": "sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz",
+ "integrity": "sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz",
+ "integrity": "sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz",
+ "integrity": "sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz",
+ "integrity": "sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz",
+ "integrity": "sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz",
+ "integrity": "sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz",
+ "integrity": "sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz",
+ "integrity": "sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/esbuild": {
+ "version": "0.19.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.8.tgz",
+ "integrity": "sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.19.8",
+ "@esbuild/android-arm64": "0.19.8",
+ "@esbuild/android-x64": "0.19.8",
+ "@esbuild/darwin-arm64": "0.19.8",
+ "@esbuild/darwin-x64": "0.19.8",
+ "@esbuild/freebsd-arm64": "0.19.8",
+ "@esbuild/freebsd-x64": "0.19.8",
+ "@esbuild/linux-arm": "0.19.8",
+ "@esbuild/linux-arm64": "0.19.8",
+ "@esbuild/linux-ia32": "0.19.8",
+ "@esbuild/linux-loong64": "0.19.8",
+ "@esbuild/linux-mips64el": "0.19.8",
+ "@esbuild/linux-ppc64": "0.19.8",
+ "@esbuild/linux-riscv64": "0.19.8",
+ "@esbuild/linux-s390x": "0.19.8",
+ "@esbuild/linux-x64": "0.19.8",
+ "@esbuild/netbsd-x64": "0.19.8",
+ "@esbuild/openbsd-x64": "0.19.8",
+ "@esbuild/sunos-x64": "0.19.8",
+ "@esbuild/win32-arm64": "0.19.8",
+ "@esbuild/win32-ia32": "0.19.8",
+ "@esbuild/win32-x64": "0.19.8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/postcss": {
+ "version": "8.4.32",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
+ "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.6.1.tgz",
+ "integrity": "sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.6.1",
+ "@rollup/rollup-android-arm64": "4.6.1",
+ "@rollup/rollup-darwin-arm64": "4.6.1",
+ "@rollup/rollup-darwin-x64": "4.6.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.6.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.6.1",
+ "@rollup/rollup-linux-arm64-musl": "4.6.1",
+ "@rollup/rollup-linux-x64-gnu": "4.6.1",
+ "@rollup/rollup-linux-x64-musl": "4.6.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.6.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.6.1",
+ "@rollup/rollup-win32-x64-msvc": "4.6.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
+ "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.6.tgz",
+ "integrity": "sha512-MD3joyAEBtV7QZPl2JVVUai6zHms3YOmLR+BpMzLlX2Yzjfcc4gTgNi09d/Rua3F4EtC8zdwPU8eQYyib4vVMQ==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.19.3",
+ "postcss": "^8.4.32",
+ "rollup": "^4.2.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/package.json b/yongjae/projects/FEDC5-3_VanillaJS_1/package.json
new file mode 100644
index 0000000..d35041d
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "fedc5-3-vanillajs-1",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "typescript": "^5.2.2",
+ "vite": "^5.0.0"
+ }
+}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/public/vite.svg b/yongjae/projects/FEDC5-3_VanillaJS_1/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
new file mode 100644
index 0000000..d356271
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -0,0 +1,71 @@
+import { setItem } from "../utils/storage";
+import { TodoState, validateState } from "../utils/validateState";
+import Header from "./Header";
+import TodoCount from "./TodoCount";
+import TodoForm from "./TodoForm";
+import TodoList from "./TodoList";
+
+interface AppProps {
+ $target: HTMLElement;
+ initialState: any;
+}
+
+// 임시 Context : this의 property를 정의하는 부분
+interface AppContext {}
+const App = function (this: AppContext, { $target, initialState }: AppProps) {
+ // ...
+ initialState = validateState(initialState);
+
+ const syncState = (state: TodoState) => {
+ const validatedState = validateState(state).map((val, idx) => ({
+ ...val,
+ id: idx,
+ }));
+ todoList.setState(validatedState);
+ todoCount.setState(validatedState);
+ };
+ new Header({
+ $target,
+ text: "Renewed Todo List",
+ });
+
+ new TodoForm({
+ $target,
+ onSubmit: (text: string) => {
+ const nextState = [
+ ...todoList.state,
+ { id: todoList.state.length, text, isCompleted: false },
+ ];
+
+ syncState(nextState);
+
+ setItem("todos", JSON.stringify(nextState));
+ },
+ });
+
+ const todoList = new TodoList({
+ $target,
+ initialState,
+ onToggle: (todoId: number) => {
+ const nextState = todoList.state.map((todo) => {
+ if (todo.id === todoId) todo.isCompleted = !todo.isCompleted;
+ return todo;
+ });
+ syncState(nextState);
+ },
+ onDelete: (todoId: number) => {
+ const nextState = todoList.state.filter((todo) => {
+ if (todo.id === todoId) return false;
+ return true;
+ });
+ syncState(nextState);
+ },
+ });
+
+ const todoCount = new TodoCount({
+ $target,
+ initialState,
+ });
+} as any as { new (props: AppProps): AppContext };
+
+export default App;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
new file mode 100644
index 0000000..b90d492
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
@@ -0,0 +1,21 @@
+interface HeaderProps {
+ $target: HTMLElement;
+ text: string;
+}
+interface HeaderContext {
+ render: () => void;
+}
+
+const Header = function (this: HeaderContext, { $target, text }: HeaderProps) {
+ const $header = document.createElement("h1");
+
+ $target.appendChild($header);
+
+ this.render = () => {
+ $header.textContent = text;
+ };
+
+ this.render();
+} as any as { new (props: HeaderProps): HeaderContext };
+
+export default Header;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
new file mode 100644
index 0000000..3629438
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -0,0 +1,40 @@
+interface TodoCountProps {
+ $target: HTMLElement;
+ initialState: StateContext[];
+}
+type StateContext = {
+ isCompleted: boolean;
+};
+// 임시 Context : this의 property를 정의하는 부분
+interface TodoCountContext {
+ state: StateContext[];
+ setState: (nextState: StateContext[]) => void;
+ render: () => void;
+}
+const TodoCount = function (
+ this: TodoCountContext,
+ { $target, initialState }: TodoCountProps
+) {
+ this.state = initialState;
+
+ const $todoCount = document.createElement("h3");
+ $target.appendChild($todoCount);
+
+ this.setState = (nextState: StateContext[]) => {
+ this.state = nextState;
+ this.render();
+ };
+
+ this.render = () => {
+ const completedNum = this.state.filter(
+ ({ isCompleted }) => isCompleted
+ ).length;
+
+ const totalNum = this.state.length;
+ $todoCount.innerHTML = `${completedNum} / ${totalNum}`;
+ };
+
+ this.render();
+} as any as { new (props: TodoCountProps): TodoCountContext };
+
+export default TodoCount;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
new file mode 100644
index 0000000..c4919a7
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -0,0 +1,45 @@
+interface TodoFormContext {
+ render: () => void;
+}
+interface TodoFormProps {
+ $target: HTMLElement;
+ onSubmit: (text: string) => void;
+}
+
+const TodoForm = function (
+ this: TodoFormContext,
+ { $target, onSubmit }: TodoFormProps
+) {
+ const $form = document.createElement("form");
+ let isInit = false;
+ $target.appendChild($form);
+
+ this.render = () => {
+ $form.innerHTML = `
+
+ `;
+ if (!isInit) {
+ $form.addEventListener("submit", (e) => {
+ e.preventDefault();
+
+ const $todo = $form.querySelector(
+ `input[name=todo]`
+ ) as HTMLInputElement;
+
+ let text = "";
+ if ($todo && $todo.value) {
+ text = $todo.value;
+ }
+
+ if (text.length > 1 && text.trim()) {
+ $todo.value = "";
+ onSubmit(text);
+ }
+ });
+ }
+ };
+
+ this.render();
+} as any as { new (props: TodoFormProps): TodoFormContext };
+
+export default TodoForm;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
new file mode 100644
index 0000000..ce4fee8
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -0,0 +1,41 @@
+type ValueContext = {
+ id: number;
+ text: string;
+ isCompleted: boolean;
+};
+type TodoItemProps = {
+ $target: HTMLElement;
+ initialValue: ValueContext;
+ onToggle: (id: number) => void;
+ onDelete: (id: number) => void;
+};
+type TodoItemContext = {
+ render: () => void;
+};
+const TodoItem = function (
+ this: TodoItemContext,
+ { $target, initialValue, onToggle, onDelete }: TodoItemProps
+) {
+ const { id, text, isCompleted } = initialValue;
+
+ const $todoItem = document.createElement("li");
+ $todoItem.textContent = text;
+ $todoItem.style.textDecoration = isCompleted ? "line-through" : "none";
+ const $todoButton = document.createElement("button");
+ $todoButton.textContent = "삭제";
+
+ $todoItem.appendChild($todoButton);
+ $target.appendChild($todoItem);
+
+ this.render = () => {
+ $todoButton.addEventListener("click", () => {
+ onDelete(id);
+ });
+ $todoItem.addEventListener("click", () => {
+ onToggle(id);
+ });
+ };
+ this.render();
+} as any as { new (props: TodoItemProps): TodoItemContext };
+
+export default TodoItem;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
new file mode 100644
index 0000000..00783e5
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -0,0 +1,45 @@
+import { setItem } from "../utils/storage";
+import { TodoState } from "../utils/validateState";
+import TodoItem from "./TodoItem";
+
+interface TodoListContext {
+ state: TodoState;
+ setState: (nextState: any) => void;
+ render: () => void;
+}
+interface TodoListProps {
+ $target: HTMLElement;
+ initialState: any;
+ onToggle: (id: number) => void;
+ onDelete: (id: number) => void;
+}
+const TodoList = function (
+ this: TodoListContext,
+ { initialState, $target, onToggle, onDelete }: TodoListProps
+) {
+ this.state = initialState;
+
+ const $todoList = document.createElement("ul");
+ $target.appendChild($todoList);
+
+ this.setState = (nextState: any) => {
+ this.state = nextState;
+ setItem("todos", JSON.stringify(this.state));
+ this.render();
+ };
+
+ this.render = () => {
+ $todoList.innerHTML = "";
+ this.state.map(
+ (itemContext: any) =>
+ new TodoItem({
+ $target: $todoList,
+ initialValue: itemContext,
+ onToggle,
+ onDelete,
+ })
+ );
+ };
+} as any as { new (props: TodoListProps): TodoListContext };
+
+export default TodoList;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
new file mode 100644
index 0000000..09e5afd
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
@@ -0,0 +1,9 @@
+export function setupCounter(element: HTMLButtonElement) {
+ let counter = 0
+ const setCounter = (count: number) => {
+ counter = count
+ element.innerHTML = `count is ${counter}`
+ }
+ element.addEventListener('click', () => setCounter(counter + 1))
+ setCounter(0)
+}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/main.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/main.ts
new file mode 100644
index 0000000..75b21cd
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/main.ts
@@ -0,0 +1,11 @@
+import { getItem } from "./utils/storage";
+import App from "./components/App.ts";
+
+const initialState = getItem("todos", []);
+
+const $app = document.querySelector("#app")!;
+
+new App({
+ $target: $app,
+ initialState,
+});
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/typescript.svg b/yongjae/projects/FEDC5-3_VanillaJS_1/src/typescript.svg
new file mode 100644
index 0000000..d91c910
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/typescript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
new file mode 100644
index 0000000..29409a6
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -0,0 +1,28 @@
+import { TodoState } from "./validateState";
+
+const storage = window.localStorage;
+
+export const setItem = (key: string, value: string) => {
+ try {
+ storage.setItem(key, value);
+ } catch (e: unknown) {
+ if (e instanceof Error) {
+ console.error(e);
+ }
+ }
+};
+
+export const getItem = (key: string, defaultValue: TodoState) => {
+ try {
+ const storedValue = storage.getItem(key);
+ if (storedValue) {
+ return JSON.parse(storedValue);
+ }
+ return defaultValue;
+ } catch (e: unknown) {
+ if (e instanceof Error) {
+ console.error(e);
+ return defaultValue;
+ }
+ }
+};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
new file mode 100644
index 0000000..b208ce8
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -0,0 +1,45 @@
+export interface TodoItemContext {
+ text: string;
+ id: number;
+ isCompleted: boolean;
+}
+export type TodoState = TodoItemContext[];
+
+// todo 상태의 유효검사 함수
+export function validateState(state: TodoState, origin = []) {
+ if (
+ Array.isArray(state) &&
+ state.every(
+ (val) =>
+ val &&
+ Object.hasOwn(val, "text") &&
+ val.text.split(" ").join("").length &&
+ Object.hasOwn(val, "isCompleted") &&
+ typeof val.isCompleted === "boolean" &&
+ Object.hasOwn(val, "id") &&
+ typeof val.id === "number"
+ )
+ )
+ return state;
+ return origin;
+}
+
+export function filterValidStorageState(state: TodoState, defaultState = []) {
+ try {
+ return state
+ .filter(
+ (val) =>
+ val &&
+ Object.hasOwn(val, "text") &&
+ val.text.split(" ").join("").length &&
+ Object.hasOwn(val, "isCompleted") &&
+ typeof val.isCompleted === "boolean" &&
+ Object.hasOwn(val, "id") &&
+ typeof val.id === "number"
+ )
+ .map((val, idx) => ({ ...val, id: idx }));
+ } catch (e) {
+ console.log(e);
+ return defaultState;
+ }
+}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/vite-env.d.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/tsconfig.json b/yongjae/projects/FEDC5-3_VanillaJS_1/tsconfig.json
new file mode 100644
index 0000000..f28fcc0
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"]
+}
From a6cbae6b61b3c8c7e6f176f958d67e47282c9844 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 11:58:55 +0900
Subject: [PATCH 02/12] =?UTF-8?q?5=EC=A3=BC=EC=B0=A8-fix:=20TodoList=20?=
=?UTF-8?q?=EC=B4=88=EA=B8=B0=20render=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index 00783e5..9fac694 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -40,6 +40,7 @@ const TodoList = function (
})
);
};
+ this.render();
} as any as { new (props: TodoListProps): TodoListContext };
export default TodoList;
From c4cacc556b3145d02b5735f4c11095eb54589bf3 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 12:26:52 +0900
Subject: [PATCH 03/12] =?UTF-8?q?refactor:=20=ED=83=80=EC=9E=85=20naming?=
=?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20?=
=?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 5 +++--
.../src/components/TodoCount.ts | 14 +++++++-------
.../FEDC5-3_VanillaJS_1/src/components/TodoItem.ts | 9 +++------
.../FEDC5-3_VanillaJS_1/src/components/TodoList.ts | 4 ++--
.../projects/FEDC5-3_VanillaJS_1/src/types/todo.ts | 6 ++++++
.../FEDC5-3_VanillaJS_1/src/utils/validateState.ts | 12 +++---------
6 files changed, 24 insertions(+), 26 deletions(-)
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index d356271..8db1880 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -1,5 +1,6 @@
+import { TodosType } from "../types/todo";
import { setItem } from "../utils/storage";
-import { TodoState, validateState } from "../utils/validateState";
+import { validateState } from "../utils/validateState";
import Header from "./Header";
import TodoCount from "./TodoCount";
import TodoForm from "./TodoForm";
@@ -16,7 +17,7 @@ const App = function (this: AppContext, { $target, initialState }: AppProps) {
// ...
initialState = validateState(initialState);
- const syncState = (state: TodoState) => {
+ const syncState = (state: TodosType) => {
const validatedState = validateState(state).map((val, idx) => ({
...val,
id: idx,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index 3629438..a1208f6 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,14 +1,14 @@
+import { TodosType } from "../types/todo";
+
interface TodoCountProps {
$target: HTMLElement;
- initialState: StateContext[];
+ initialState: TodosType;
}
-type StateContext = {
- isCompleted: boolean;
-};
+
// 임시 Context : this의 property를 정의하는 부분
interface TodoCountContext {
- state: StateContext[];
- setState: (nextState: StateContext[]) => void;
+ state: TodosType;
+ setState: (nextState: TodosType) => void;
render: () => void;
}
const TodoCount = function (
@@ -20,7 +20,7 @@ const TodoCount = function (
const $todoCount = document.createElement("h3");
$target.appendChild($todoCount);
- this.setState = (nextState: StateContext[]) => {
+ this.setState = (nextState: TodosType) => {
this.state = nextState;
this.render();
};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index ce4fee8..8858380 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,11 +1,8 @@
-type ValueContext = {
- id: number;
- text: string;
- isCompleted: boolean;
-};
+import { TodoType } from "../types/todo";
+
type TodoItemProps = {
$target: HTMLElement;
- initialValue: ValueContext;
+ initialValue: TodoType;
onToggle: (id: number) => void;
onDelete: (id: number) => void;
};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index 9fac694..b6258ba 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,9 +1,9 @@
+import { TodosType } from "../types/todo";
import { setItem } from "../utils/storage";
-import { TodoState } from "../utils/validateState";
import TodoItem from "./TodoItem";
interface TodoListContext {
- state: TodoState;
+ state: TodosType;
setState: (nextState: any) => void;
render: () => void;
}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
new file mode 100644
index 0000000..19b0869
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
@@ -0,0 +1,6 @@
+export interface TodoType {
+ text: string;
+ id: number;
+ isCompleted: boolean;
+}
+export type TodosType = TodoType[];
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index b208ce8..814a940 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,12 +1,6 @@
-export interface TodoItemContext {
- text: string;
- id: number;
- isCompleted: boolean;
-}
-export type TodoState = TodoItemContext[];
-
+import { TodosType } from "../types/todo";
// todo 상태의 유효검사 함수
-export function validateState(state: TodoState, origin = []) {
+export function validateState(state: TodosType, origin = []) {
if (
Array.isArray(state) &&
state.every(
@@ -24,7 +18,7 @@ export function validateState(state: TodoState, origin = []) {
return origin;
}
-export function filterValidStorageState(state: TodoState, defaultState = []) {
+export function filterValidStorageState(state: TodosType, defaultState = []) {
try {
return state
.filter(
From c7900a2095d817b2d787d0f189fe1add77f2314e Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 17:26:10 +0900
Subject: [PATCH 04/12] =?UTF-8?q?refactor:=20storage=20=EB=AA=A8=EB=93=88?=
=?UTF-8?q?=20=EC=A0=9C=EB=84=A4=EB=A6=AD=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F?=
=?UTF-8?q?=20=EC=9D=B8=EC=88=98=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 2 +-
.../src/components/TodoList.ts | 2 +-
.../projects/FEDC5-3_VanillaJS_1/src/counter.ts | 9 ---------
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 17 +++++++++++++----
.../src/utils/validateState.ts | 9 +++++++--
5 files changed, 22 insertions(+), 17 deletions(-)
delete mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index 8db1880..a1b3dcc 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -40,7 +40,7 @@ const App = function (this: AppContext, { $target, initialState }: AppProps) {
syncState(nextState);
- setItem("todos", JSON.stringify(nextState));
+ setItem("todos", nextState);
},
});
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index b6258ba..d8a92ed 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -24,7 +24,7 @@ const TodoList = function (
this.setState = (nextState: any) => {
this.state = nextState;
- setItem("todos", JSON.stringify(this.state));
+ setItem("todos", this.state);
this.render();
};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
deleted file mode 100644
index 09e5afd..0000000
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/counter.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export function setupCounter(element: HTMLButtonElement) {
- let counter = 0
- const setCounter = (count: number) => {
- counter = count
- element.innerHTML = `count is ${counter}`
- }
- element.addEventListener('click', () => setCounter(counter + 1))
- setCounter(0)
-}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index 29409a6..764fdc3 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,10 +1,16 @@
-import { TodoState } from "./validateState";
+import { TodosType } from "../types/todo";
+
+export type setStorage = (key: string, value: T) => void;
+export type getStorage = (key: string, defaultValue: T) => T;
const storage = window.localStorage;
-export const setItem = (key: string, value: string) => {
+export const setItem: setStorage = (
+ key: string,
+ value: TodosType
+) => {
try {
- storage.setItem(key, value);
+ storage.setItem(key, JSON.stringify(value));
} catch (e: unknown) {
if (e instanceof Error) {
console.error(e);
@@ -12,7 +18,10 @@ export const setItem = (key: string, value: string) => {
}
};
-export const getItem = (key: string, defaultValue: TodoState) => {
+export const getItem: getStorage = (
+ key: string,
+ defaultValue = [] as TodosType
+) => {
try {
const storedValue = storage.getItem(key);
if (storedValue) {
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index 814a940..b9108f6 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -18,7 +18,10 @@ export function validateState(state: TodosType, origin = []) {
return origin;
}
-export function filterValidStorageState(state: TodosType, defaultState = []) {
+export function filterValidStorageState(
+ state: TodosType,
+ defaultState = [] as TodosType
+) {
try {
return state
.filter(
@@ -33,7 +36,9 @@ export function filterValidStorageState(state: TodosType, defaultState = []) {
)
.map((val, idx) => ({ ...val, id: idx }));
} catch (e) {
- console.log(e);
+ if (e instanceof Error) {
+ console.log(e);
+ }
return defaultState;
}
}
From 550200344029d62db8092f878347d53fdc3c42ef Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 17:39:06 +0900
Subject: [PATCH 05/12] =?UTF-8?q?refactor:=20any=20=ED=83=80=EC=9D=B4?=
=?UTF-8?q?=ED=95=91=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/TodoList.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index d8a92ed..bc76f99 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -4,12 +4,12 @@ import TodoItem from "./TodoItem";
interface TodoListContext {
state: TodosType;
- setState: (nextState: any) => void;
+ setState: (nextState: TodosType) => void;
render: () => void;
}
interface TodoListProps {
$target: HTMLElement;
- initialState: any;
+ initialState: TodosType;
onToggle: (id: number) => void;
onDelete: (id: number) => void;
}
@@ -22,7 +22,7 @@ const TodoList = function (
const $todoList = document.createElement("ul");
$target.appendChild($todoList);
- this.setState = (nextState: any) => {
+ this.setState = (nextState: TodosType) => {
this.state = nextState;
setItem("todos", this.state);
this.render();
@@ -31,7 +31,7 @@ const TodoList = function (
this.render = () => {
$todoList.innerHTML = "";
this.state.map(
- (itemContext: any) =>
+ (itemContext) =>
new TodoItem({
$target: $todoList,
initialValue: itemContext,
From db556ee797bd3123d00eb99e680e7bf7bbb381f6 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 18:08:12 +0900
Subject: [PATCH 06/12] =?UTF-8?q?refactor:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?=
=?UTF-8?q?=ED=8A=B8=20context=20=ED=83=80=EC=9D=B4=ED=95=91=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 2 +-
.../src/components/Header.ts | 12 +++++-----
.../src/components/TodoCount.ts | 12 +++-------
.../src/components/TodoForm.ts | 9 ++++----
.../src/components/TodoItem.ts | 10 ++++-----
.../src/components/TodoList.ts | 11 +++-------
.../FEDC5-3_VanillaJS_1/src/types/todo.ts | 22 +++++++++++++++++++
7 files changed, 44 insertions(+), 34 deletions(-)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index a1b3dcc..6fd40d3 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -8,7 +8,7 @@ import TodoList from "./TodoList";
interface AppProps {
$target: HTMLElement;
- initialState: any;
+ initialState: TodosType;
}
// 임시 Context : this의 property를 정의하는 부분
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
index b90d492..1169810 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
@@ -1,12 +1,14 @@
+import { TodoComponentStatelessContext } from "../types/todo";
+
interface HeaderProps {
$target: HTMLElement;
text: string;
}
-interface HeaderContext {
- render: () => void;
-}
-const Header = function (this: HeaderContext, { $target, text }: HeaderProps) {
+const Header = function (
+ this: TodoComponentStatelessContext,
+ { $target, text }: HeaderProps
+) {
const $header = document.createElement("h1");
$target.appendChild($header);
@@ -16,6 +18,6 @@ const Header = function (this: HeaderContext, { $target, text }: HeaderProps) {
};
this.render();
-} as any as { new (props: HeaderProps): HeaderContext };
+} as any as { new (props: HeaderProps): TodoComponentStatelessContext };
export default Header;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index a1208f6..1566776 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,18 +1,12 @@
-import { TodosType } from "../types/todo";
+import { TodoComponentStatefulContext, TodosType } from "../types/todo";
interface TodoCountProps {
$target: HTMLElement;
initialState: TodosType;
}
-// 임시 Context : this의 property를 정의하는 부분
-interface TodoCountContext {
- state: TodosType;
- setState: (nextState: TodosType) => void;
- render: () => void;
-}
const TodoCount = function (
- this: TodoCountContext,
+ this: TodoComponentStatefulContext,
{ $target, initialState }: TodoCountProps
) {
this.state = initialState;
@@ -35,6 +29,6 @@ const TodoCount = function (
};
this.render();
-} as any as { new (props: TodoCountProps): TodoCountContext };
+} as any as { new (props: TodoCountProps): TodoComponentStatefulContext };
export default TodoCount;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
index c4919a7..1cfdda1 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -1,13 +1,12 @@
-interface TodoFormContext {
- render: () => void;
-}
+import { TodoComponentStatelessContext } from "../types/todo";
+
interface TodoFormProps {
$target: HTMLElement;
onSubmit: (text: string) => void;
}
const TodoForm = function (
- this: TodoFormContext,
+ this: TodoComponentStatelessContext,
{ $target, onSubmit }: TodoFormProps
) {
const $form = document.createElement("form");
@@ -40,6 +39,6 @@ const TodoForm = function (
};
this.render();
-} as any as { new (props: TodoFormProps): TodoFormContext };
+} as any as { new (props: TodoFormProps): TodoComponentStatelessContext };
export default TodoForm;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index 8858380..63f3473 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,4 +1,4 @@
-import { TodoType } from "../types/todo";
+import { TodoComponentStatelessContext, TodoType } from "../types/todo";
type TodoItemProps = {
$target: HTMLElement;
@@ -6,11 +6,9 @@ type TodoItemProps = {
onToggle: (id: number) => void;
onDelete: (id: number) => void;
};
-type TodoItemContext = {
- render: () => void;
-};
+
const TodoItem = function (
- this: TodoItemContext,
+ this: TodoComponentStatelessContext,
{ $target, initialValue, onToggle, onDelete }: TodoItemProps
) {
const { id, text, isCompleted } = initialValue;
@@ -33,6 +31,6 @@ const TodoItem = function (
});
};
this.render();
-} as any as { new (props: TodoItemProps): TodoItemContext };
+} as any as { new (props: TodoItemProps): TodoComponentStatelessContext };
export default TodoItem;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index bc76f99..e8cdbc9 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,12 +1,7 @@
-import { TodosType } from "../types/todo";
+import { TodoComponentStatefulContext, TodosType } from "../types/todo";
import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
-interface TodoListContext {
- state: TodosType;
- setState: (nextState: TodosType) => void;
- render: () => void;
-}
interface TodoListProps {
$target: HTMLElement;
initialState: TodosType;
@@ -14,7 +9,7 @@ interface TodoListProps {
onDelete: (id: number) => void;
}
const TodoList = function (
- this: TodoListContext,
+ this: TodoComponentStatefulContext,
{ initialState, $target, onToggle, onDelete }: TodoListProps
) {
this.state = initialState;
@@ -41,6 +36,6 @@ const TodoList = function (
);
};
this.render();
-} as any as { new (props: TodoListProps): TodoListContext };
+} as any as { new (props: TodoListProps): TodoComponentStatefulContext };
export default TodoList;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
index 19b0869..f2acec3 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
@@ -4,3 +4,25 @@ export interface TodoType {
isCompleted: boolean;
}
export type TodosType = TodoType[];
+
+// 컴포넌트 구조 typing
+interface CoreComponentContext {
+ state?: T;
+ setState?: (nextState: T) => void;
+ render: () => void;
+}
+type StatefulComponentContext = {
+ [K in keyof CoreComponentContext]-?: CoreComponentContext[K];
+};
+type StatelessComponentContext = Omit<
+ CoreComponentContext,
+ "state" | "setState"
+>;
+export type TodoComponentContext = CoreComponentContext;
+export type TodoComponentStatefulContext = StatefulComponentContext;
+export type TodoComponentStatelessContext =
+ StatelessComponentContext;
+
+interface CoreComponentProps {
+ $target: HTMLElement;
+}
From cc7092da1f9dc48cf4aaf16170ffc07effcc1a71 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Mon, 11 Dec 2023 19:07:44 +0900
Subject: [PATCH 07/12] =?UTF-8?q?refactor:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?=
=?UTF-8?q?=ED=8A=B8=20props=20=ED=83=80=EC=9D=B4=ED=95=91=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 15 ++++++---------
.../src/components/Header.ts | 10 +++++-----
.../src/components/TodoCount.ts | 17 +++++++++--------
.../src/components/TodoForm.ts | 10 ++++++----
.../src/components/TodoItem.ts | 11 +++++++----
.../src/components/TodoList.ts | 12 +++++++-----
.../src/types/{todo.ts => index.ts} | 14 +++++++++++++-
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 2 +-
.../src/utils/validateState.ts | 2 +-
9 files changed, 55 insertions(+), 38 deletions(-)
rename yongjae/projects/FEDC5-3_VanillaJS_1/src/types/{todo.ts => index.ts} (67%)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index 6fd40d3..c658c74 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -1,4 +1,4 @@
-import { TodosType } from "../types/todo";
+import { TodoComponentStatefulProps, TodosType } from "../types";
import { setItem } from "../utils/storage";
import { validateState } from "../utils/validateState";
import Header from "./Header";
@@ -6,14 +6,11 @@ import TodoCount from "./TodoCount";
import TodoForm from "./TodoForm";
import TodoList from "./TodoList";
-interface AppProps {
- $target: HTMLElement;
- initialState: TodosType;
-}
-
-// 임시 Context : this의 property를 정의하는 부분
interface AppContext {}
-const App = function (this: AppContext, { $target, initialState }: AppProps) {
+const App = function (
+ this: AppContext,
+ { $target, initialState }: TodoComponentStatefulProps
+) {
// ...
initialState = validateState(initialState);
@@ -67,6 +64,6 @@ const App = function (this: AppContext, { $target, initialState }: AppProps) {
$target,
initialState,
});
-} as any as { new (props: AppProps): AppContext };
+} as any as { new (props: TodoComponentStatefulProps): AppContext };
export default App;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
index 1169810..ad82845 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
@@ -1,9 +1,9 @@
-import { TodoComponentStatelessContext } from "../types/todo";
+import {
+ TodoComponentStatelessContext,
+ TodoComponentStatelessProps,
+} from "../types";
-interface HeaderProps {
- $target: HTMLElement;
- text: string;
-}
+type HeaderProps = TodoComponentStatelessProps<{ text: string }>;
const Header = function (
this: TodoComponentStatelessContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index 1566776..ead33c2 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,13 +1,12 @@
-import { TodoComponentStatefulContext, TodosType } from "../types/todo";
-
-interface TodoCountProps {
- $target: HTMLElement;
- initialState: TodosType;
-}
+import {
+ TodoComponentStatefulContext,
+ TodoComponentStatefulProps,
+ TodosType,
+} from "../types";
const TodoCount = function (
this: TodoComponentStatefulContext,
- { $target, initialState }: TodoCountProps
+ { $target, initialState }: TodoComponentStatefulProps
) {
this.state = initialState;
@@ -29,6 +28,8 @@ const TodoCount = function (
};
this.render();
-} as any as { new (props: TodoCountProps): TodoComponentStatefulContext };
+} as any as {
+ new (props: TodoComponentStatefulProps): TodoComponentStatefulContext;
+};
export default TodoCount;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
index 1cfdda1..a86a886 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -1,9 +1,11 @@
-import { TodoComponentStatelessContext } from "../types/todo";
+import {
+ TodoComponentStatelessContext,
+ TodoComponentStatelessProps,
+} from "../types";
-interface TodoFormProps {
- $target: HTMLElement;
+type TodoFormProps = TodoComponentStatelessProps<{
onSubmit: (text: string) => void;
-}
+}>;
const TodoForm = function (
this: TodoComponentStatelessContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index 63f3473..83ba2e0 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,11 +1,14 @@
-import { TodoComponentStatelessContext, TodoType } from "../types/todo";
+import {
+ TodoComponentStatelessContext,
+ TodoComponentStatelessProps,
+ TodoType,
+} from "../types";
-type TodoItemProps = {
- $target: HTMLElement;
+type TodoItemProps = TodoComponentStatelessProps<{
initialValue: TodoType;
onToggle: (id: number) => void;
onDelete: (id: number) => void;
-};
+}>;
const TodoItem = function (
this: TodoComponentStatelessContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index e8cdbc9..0fef739 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,13 +1,15 @@
-import { TodoComponentStatefulContext, TodosType } from "../types/todo";
+import {
+ TodoComponentStatefulContext,
+ TodoComponentStatefulProps,
+ TodosType,
+} from "../types";
import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
-interface TodoListProps {
- $target: HTMLElement;
- initialState: TodosType;
+type TodoListProps = TodoComponentStatefulProps<{
onToggle: (id: number) => void;
onDelete: (id: number) => void;
-}
+}>;
const TodoList = function (
this: TodoComponentStatefulContext,
{ initialState, $target, onToggle, onDelete }: TodoListProps
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
similarity index 67%
rename from yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
rename to yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
index f2acec3..ed5d61d 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/todo.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
@@ -23,6 +23,18 @@ export type TodoComponentStatefulContext = StatefulComponentContext;
export type TodoComponentStatelessContext =
StatelessComponentContext;
-interface CoreComponentProps {
+export interface CoreComponentProps {
$target: HTMLElement;
}
+
+export interface StatefulComponentProps extends CoreComponentProps {
+ initialState: T;
+}
+
+export type TodoComponentStatefulProps =
+ StatefulComponentProps & {
+ [K in keyof T]: T[K];
+ };
+export type TodoComponentStatelessProps = CoreComponentProps & {
+ [K in keyof T]: T[K];
+};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index 764fdc3..aec039d 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,4 +1,4 @@
-import { TodosType } from "../types/todo";
+import { TodosType } from "../types";
export type setStorage = (key: string, value: T) => void;
export type getStorage = (key: string, defaultValue: T) => T;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index b9108f6..f20cf37 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,4 +1,4 @@
-import { TodosType } from "../types/todo";
+import { TodosType } from "../types";
// todo 상태의 유효검사 함수
export function validateState(state: TodosType, origin = []) {
if (
From cb5099de4ac2d7e817c109361f5121617e80d2ed Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Thu, 14 Dec 2023 17:22:51 +0900
Subject: [PATCH 08/12] =?UTF-8?q?refactor:=20state=20id=EB=A5=BC=20string?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 11 +++-----
.../src/components/TodoForm.ts | 10 +++----
.../src/components/TodoItem.ts | 4 +--
.../src/components/TodoList.ts | 4 +--
.../FEDC5-3_VanillaJS_1/src/types/index.ts | 2 +-
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 2 +-
.../src/utils/validateState.ts | 28 +++++++++----------
7 files changed, 28 insertions(+), 33 deletions(-)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index c658c74..e83c4d9 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -15,10 +15,7 @@ const App = function (
initialState = validateState(initialState);
const syncState = (state: TodosType) => {
- const validatedState = validateState(state).map((val, idx) => ({
- ...val,
- id: idx,
- }));
+ const validatedState = validateState(state);
todoList.setState(validatedState);
todoCount.setState(validatedState);
};
@@ -32,7 +29,7 @@ const App = function (
onSubmit: (text: string) => {
const nextState = [
...todoList.state,
- { id: todoList.state.length, text, isCompleted: false },
+ { id: String(Date.now()), text, isCompleted: false },
];
syncState(nextState);
@@ -44,14 +41,14 @@ const App = function (
const todoList = new TodoList({
$target,
initialState,
- onToggle: (todoId: number) => {
+ onToggle: (todoId: string) => {
const nextState = todoList.state.map((todo) => {
if (todo.id === todoId) todo.isCompleted = !todo.isCompleted;
return todo;
});
syncState(nextState);
},
- onDelete: (todoId: number) => {
+ onDelete: (todoId: string) => {
const nextState = todoList.state.filter((todo) => {
if (todo.id === todoId) return false;
return true;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
index a86a886..240a991 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -23,9 +23,7 @@ const TodoForm = function (
$form.addEventListener("submit", (e) => {
e.preventDefault();
- const $todo = $form.querySelector(
- `input[name=todo]`
- ) as HTMLInputElement;
+ const $todo = $form.querySelector(`input[name=todo]`);
let text = "";
if ($todo && $todo.value) {
@@ -33,8 +31,10 @@ const TodoForm = function (
}
if (text.length > 1 && text.trim()) {
- $todo.value = "";
- onSubmit(text);
+ if ($todo) {
+ $todo.value = "";
+ onSubmit(text);
+ }
}
});
}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index 83ba2e0..0c7bab4 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -6,8 +6,8 @@ import {
type TodoItemProps = TodoComponentStatelessProps<{
initialValue: TodoType;
- onToggle: (id: number) => void;
- onDelete: (id: number) => void;
+ onToggle: (id: string) => void;
+ onDelete: (id: string) => void;
}>;
const TodoItem = function (
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index 0fef739..ac45eb0 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -7,8 +7,8 @@ import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
type TodoListProps = TodoComponentStatefulProps<{
- onToggle: (id: number) => void;
- onDelete: (id: number) => void;
+ onToggle: (id: string) => void;
+ onDelete: (id: string) => void;
}>;
const TodoList = function (
this: TodoComponentStatefulContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
index ed5d61d..8c529e7 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
@@ -1,6 +1,6 @@
export interface TodoType {
text: string;
- id: number;
+ id: string;
isCompleted: boolean;
}
export type TodosType = TodoType[];
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index aec039d..cb9434d 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -20,7 +20,7 @@ export const setItem: setStorage = (
export const getItem: getStorage = (
key: string,
- defaultValue = [] as TodosType
+ defaultValue = []
) => {
try {
const storedValue = storage.getItem(key);
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index f20cf37..310188d 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,6 +1,6 @@
import { TodosType } from "../types";
// todo 상태의 유효검사 함수
-export function validateState(state: TodosType, origin = []) {
+export function validateState(state: TodosType, origin: TodosType = []) {
if (
Array.isArray(state) &&
state.every(
@@ -11,7 +11,7 @@ export function validateState(state: TodosType, origin = []) {
Object.hasOwn(val, "isCompleted") &&
typeof val.isCompleted === "boolean" &&
Object.hasOwn(val, "id") &&
- typeof val.id === "number"
+ typeof val.id === "string"
)
)
return state;
@@ -20,21 +20,19 @@ export function validateState(state: TodosType, origin = []) {
export function filterValidStorageState(
state: TodosType,
- defaultState = [] as TodosType
+ defaultState: TodosType = []
) {
try {
- return state
- .filter(
- (val) =>
- val &&
- Object.hasOwn(val, "text") &&
- val.text.split(" ").join("").length &&
- Object.hasOwn(val, "isCompleted") &&
- typeof val.isCompleted === "boolean" &&
- Object.hasOwn(val, "id") &&
- typeof val.id === "number"
- )
- .map((val, idx) => ({ ...val, id: idx }));
+ return state.filter(
+ (val) =>
+ val &&
+ Object.hasOwn(val, "text") &&
+ val.text.split(" ").join("").length &&
+ Object.hasOwn(val, "isCompleted") &&
+ typeof val.isCompleted === "boolean" &&
+ Object.hasOwn(val, "id") &&
+ typeof val.id === "string"
+ );
} catch (e) {
if (e instanceof Error) {
console.log(e);
From c3a260dec4529c79ab4b2d75bd02862e1de5d0af Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Thu, 14 Dec 2023 17:30:05 +0900
Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20type=20=EB=84=A4=EC=9D=B4?=
=?UTF-8?q?=EB=B0=8D=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 4 ++--
.../FEDC5-3_VanillaJS_1/src/components/TodoCount.ts | 4 ++--
.../FEDC5-3_VanillaJS_1/src/components/TodoItem.ts | 4 ++--
.../FEDC5-3_VanillaJS_1/src/components/TodoList.ts | 4 ++--
.../projects/FEDC5-3_VanillaJS_1/src/types/index.ts | 13 ++++++-------
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 12 +++---------
.../FEDC5-3_VanillaJS_1/src/utils/validateState.ts | 8 ++++----
7 files changed, 21 insertions(+), 28 deletions(-)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index e83c4d9..1779841 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -1,4 +1,4 @@
-import { TodoComponentStatefulProps, TodosType } from "../types";
+import { TodoComponentStatefulProps, Todos } from "../types";
import { setItem } from "../utils/storage";
import { validateState } from "../utils/validateState";
import Header from "./Header";
@@ -14,7 +14,7 @@ const App = function (
// ...
initialState = validateState(initialState);
- const syncState = (state: TodosType) => {
+ const syncState = (state: Todos) => {
const validatedState = validateState(state);
todoList.setState(validatedState);
todoCount.setState(validatedState);
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index ead33c2..cafc720 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,7 +1,7 @@
import {
TodoComponentStatefulContext,
TodoComponentStatefulProps,
- TodosType,
+ Todos,
} from "../types";
const TodoCount = function (
@@ -13,7 +13,7 @@ const TodoCount = function (
const $todoCount = document.createElement("h3");
$target.appendChild($todoCount);
- this.setState = (nextState: TodosType) => {
+ this.setState = (nextState: Todos) => {
this.state = nextState;
this.render();
};
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index 0c7bab4..816d4f1 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,11 +1,11 @@
import {
TodoComponentStatelessContext,
TodoComponentStatelessProps,
- TodoType,
+ Todo,
} from "../types";
type TodoItemProps = TodoComponentStatelessProps<{
- initialValue: TodoType;
+ initialValue: Todo;
onToggle: (id: string) => void;
onDelete: (id: string) => void;
}>;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index ac45eb0..cc95c6b 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,7 +1,7 @@
import {
TodoComponentStatefulContext,
TodoComponentStatefulProps,
- TodosType,
+ Todos,
} from "../types";
import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
@@ -19,7 +19,7 @@ const TodoList = function (
const $todoList = document.createElement("ul");
$target.appendChild($todoList);
- this.setState = (nextState: TodosType) => {
+ this.setState = (nextState: Todos) => {
this.state = nextState;
setItem("todos", this.state);
this.render();
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
index 8c529e7..53b1b0b 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
@@ -1,9 +1,9 @@
-export interface TodoType {
+export interface Todo {
text: string;
id: string;
isCompleted: boolean;
}
-export type TodosType = TodoType[];
+export type Todos = Todo[];
// 컴포넌트 구조 typing
interface CoreComponentContext {
@@ -18,10 +18,9 @@ type StatelessComponentContext = Omit<
CoreComponentContext,
"state" | "setState"
>;
-export type TodoComponentContext = CoreComponentContext;
-export type TodoComponentStatefulContext = StatefulComponentContext;
-export type TodoComponentStatelessContext =
- StatelessComponentContext;
+export type TodoComponentContext = CoreComponentContext;
+export type TodoComponentStatefulContext = StatefulComponentContext;
+export type TodoComponentStatelessContext = StatelessComponentContext;
export interface CoreComponentProps {
$target: HTMLElement;
@@ -32,7 +31,7 @@ export interface StatefulComponentProps extends CoreComponentProps {
}
export type TodoComponentStatefulProps =
- StatefulComponentProps & {
+ StatefulComponentProps & {
[K in keyof T]: T[K];
};
export type TodoComponentStatelessProps = CoreComponentProps & {
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index cb9434d..cf7e78b 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,14 +1,11 @@
-import { TodosType } from "../types";
+import { Todos } from "../types";
export type setStorage = (key: string, value: T) => void;
export type getStorage = (key: string, defaultValue: T) => T;
const storage = window.localStorage;
-export const setItem: setStorage = (
- key: string,
- value: TodosType
-) => {
+export const setItem: setStorage = (key: string, value: Todos) => {
try {
storage.setItem(key, JSON.stringify(value));
} catch (e: unknown) {
@@ -18,10 +15,7 @@ export const setItem: setStorage = (
}
};
-export const getItem: getStorage = (
- key: string,
- defaultValue = []
-) => {
+export const getItem: getStorage = (key: string, defaultValue = []) => {
try {
const storedValue = storage.getItem(key);
if (storedValue) {
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index 310188d..4bb9bc2 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,6 +1,6 @@
-import { TodosType } from "../types";
+import { Todos } from "../types";
// todo 상태의 유효검사 함수
-export function validateState(state: TodosType, origin: TodosType = []) {
+export function validateState(state: Todos, origin: Todos = []) {
if (
Array.isArray(state) &&
state.every(
@@ -19,8 +19,8 @@ export function validateState(state: TodosType, origin: TodosType = []) {
}
export function filterValidStorageState(
- state: TodosType,
- defaultState: TodosType = []
+ state: Todos,
+ defaultState: Todos = []
) {
try {
return state.filter(
From ab379cd6e060dde686c02ef53f569dbdadef9f3a Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Thu, 14 Dec 2023 17:46:33 +0900
Subject: [PATCH 10/12] =?UTF-8?q?refactor:=20=EC=97=90=EB=9F=AC=20?=
=?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20constants=EB=A1=9C=20=EC=A0=95?=
=?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../projects/FEDC5-3_VanillaJS_1/src/constants.ts | 14 ++++++++++++++
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 5 +++--
.../FEDC5-3_VanillaJS_1/src/utils/validateState.ts | 7 +++++--
3 files changed, 22 insertions(+), 4 deletions(-)
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/constants.ts
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/constants.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/constants.ts
new file mode 100644
index 0000000..f9c8627
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/constants.ts
@@ -0,0 +1,14 @@
+export const STORAGE_KEY = "todos";
+
+const KNOWN_ERROR_MESSAGES = {
+ invalidState: "올바르지 않은 상태 형식입니다",
+};
+
+export const ERROR_MESSAGES = new Proxy(KNOWN_ERROR_MESSAGES, {
+ get: function (target: { [key: string]: string }, prop: string) {
+ if (prop.length < 1) {
+ return "알 수 없는 에러입니다.";
+ }
+ return target[prop] ?? prop;
+ },
+});
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index cf7e78b..d1b6bad 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,3 +1,4 @@
+import { ERROR_MESSAGES } from "../constants";
import { Todos } from "../types";
export type setStorage = (key: string, value: T) => void;
@@ -10,7 +11,7 @@ export const setItem: setStorage = (key: string, value: Todos) => {
storage.setItem(key, JSON.stringify(value));
} catch (e: unknown) {
if (e instanceof Error) {
- console.error(e);
+ console.warn(ERROR_MESSAGES[e.message]);
}
}
};
@@ -24,7 +25,7 @@ export const getItem: getStorage = (key: string, defaultValue = []) => {
return defaultValue;
} catch (e: unknown) {
if (e instanceof Error) {
- console.error(e);
+ console.warn(ERROR_MESSAGES[e.message]);
return defaultValue;
}
}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index 4bb9bc2..96dcf00 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,3 +1,4 @@
+import { ERROR_MESSAGES } from "../constants";
import { Todos } from "../types";
// todo 상태의 유효검사 함수
export function validateState(state: Todos, origin: Todos = []) {
@@ -13,8 +14,10 @@ export function validateState(state: Todos, origin: Todos = []) {
Object.hasOwn(val, "id") &&
typeof val.id === "string"
)
- )
+ ) {
return state;
+ }
+ console.warn(ERROR_MESSAGES["invalidState"]);
return origin;
}
@@ -35,7 +38,7 @@ export function filterValidStorageState(
);
} catch (e) {
if (e instanceof Error) {
- console.log(e);
+ console.warn(ERROR_MESSAGES[e.message]);
}
return defaultState;
}
From adf13a867f4af37523ad03953d1fb6e90fc61e30 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Thu, 14 Dec 2023 17:52:17 +0900
Subject: [PATCH 11/12] =?UTF-8?q?refactor:=20types=20=EC=84=A0=EC=96=B8=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../projects/FEDC5-3_VanillaJS_1/src/components/App.ts | 3 ++-
.../FEDC5-3_VanillaJS_1/src/components/Header.ts | 2 +-
.../FEDC5-3_VanillaJS_1/src/components/TodoCount.ts | 4 ++--
.../FEDC5-3_VanillaJS_1/src/components/TodoForm.ts | 2 +-
.../FEDC5-3_VanillaJS_1/src/components/TodoItem.ts | 4 ++--
.../FEDC5-3_VanillaJS_1/src/components/TodoList.ts | 4 ++--
.../src/types/{index.ts => components.ts} | 10 +++-------
.../projects/FEDC5-3_VanillaJS_1/src/types/states.ts | 6 ++++++
.../projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts | 2 +-
.../FEDC5-3_VanillaJS_1/src/utils/validateState.ts | 2 +-
10 files changed, 21 insertions(+), 18 deletions(-)
rename yongjae/projects/FEDC5-3_VanillaJS_1/src/types/{index.ts => components.ts} (89%)
create mode 100644 yongjae/projects/FEDC5-3_VanillaJS_1/src/types/states.ts
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index 1779841..90c9bdb 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -1,4 +1,5 @@
-import { TodoComponentStatefulProps, Todos } from "../types";
+import { TodoComponentStatefulProps } from "../types/components";
+import { Todos } from "../types/states";
import { setItem } from "../utils/storage";
import { validateState } from "../utils/validateState";
import Header from "./Header";
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
index ad82845..9e119c4 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
@@ -1,7 +1,7 @@
import {
TodoComponentStatelessContext,
TodoComponentStatelessProps,
-} from "../types";
+} from "../types/components";
type HeaderProps = TodoComponentStatelessProps<{ text: string }>;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index cafc720..b57d460 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,8 +1,8 @@
import {
TodoComponentStatefulContext,
TodoComponentStatefulProps,
- Todos,
-} from "../types";
+} from "../types/components";
+import { Todos } from "../types/states";
const TodoCount = function (
this: TodoComponentStatefulContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
index 240a991..b928fe9 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -1,7 +1,7 @@
import {
TodoComponentStatelessContext,
TodoComponentStatelessProps,
-} from "../types";
+} from "../types/components";
type TodoFormProps = TodoComponentStatelessProps<{
onSubmit: (text: string) => void;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index 816d4f1..ebb5698 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,8 +1,8 @@
import {
TodoComponentStatelessContext,
TodoComponentStatelessProps,
- Todo,
-} from "../types";
+} from "../types/components";
+import { Todo } from "../types/states";
type TodoItemProps = TodoComponentStatelessProps<{
initialValue: Todo;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index cc95c6b..e869784 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,8 +1,8 @@
import {
TodoComponentStatefulContext,
TodoComponentStatefulProps,
- Todos,
-} from "../types";
+} from "../types/components";
+import { Todos } from "../types/states";
import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
similarity index 89%
rename from yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
rename to yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
index 53b1b0b..cb3c932 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/index.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
@@ -1,11 +1,6 @@
-export interface Todo {
- text: string;
- id: string;
- isCompleted: boolean;
-}
-export type Todos = Todo[];
-
+import { Todos } from "./states";
// 컴포넌트 구조 typing
+// 컴포넌트 Context
interface CoreComponentContext {
state?: T;
setState?: (nextState: T) => void;
@@ -22,6 +17,7 @@ export type TodoComponentContext = CoreComponentContext;
export type TodoComponentStatefulContext = StatefulComponentContext;
export type TodoComponentStatelessContext = StatelessComponentContext;
+// 컴포넌트 Props
export interface CoreComponentProps {
$target: HTMLElement;
}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/states.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/states.ts
new file mode 100644
index 0000000..f20587b
--- /dev/null
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/states.ts
@@ -0,0 +1,6 @@
+export interface Todo {
+ text: string;
+ id: string;
+ isCompleted: boolean;
+}
+export type Todos = Todo[];
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index d1b6bad..0c5d1d1 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,5 +1,5 @@
import { ERROR_MESSAGES } from "../constants";
-import { Todos } from "../types";
+import { Todos } from "../types/components";
export type setStorage = (key: string, value: T) => void;
export type getStorage = (key: string, defaultValue: T) => T;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index 96dcf00..076d2f0 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,5 +1,5 @@
import { ERROR_MESSAGES } from "../constants";
-import { Todos } from "../types";
+import { Todos } from "../types/components";
// todo 상태의 유효검사 함수
export function validateState(state: Todos, origin: Todos = []) {
if (
From 0c1b3b713c8fed226bcaa82f28101f42e09d2277 Mon Sep 17 00:00:00 2001
From: yongjaechoi <88219703+yjc2021@users.noreply.github.com>
Date: Thu, 14 Dec 2023 18:10:06 +0900
Subject: [PATCH 12/12] =?UTF-8?q?refactor:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?=
=?UTF-8?q?=ED=8A=B8=20type=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FEDC5-3_VanillaJS_1/src/components/App.ts | 9 ++--
.../src/components/Header.ts | 4 +-
.../src/components/TodoCount.ts | 6 +--
.../src/components/TodoForm.ts | 6 +--
.../src/components/TodoItem.ts | 9 +---
.../src/components/TodoList.ts | 6 +--
.../src/types/components.ts | 53 +++++++++++--------
.../FEDC5-3_VanillaJS_1/src/utils/storage.ts | 2 +-
.../src/utils/validateState.ts | 2 +-
9 files changed, 44 insertions(+), 53 deletions(-)
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
index 90c9bdb..9cf336a 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/App.ts
@@ -1,4 +1,4 @@
-import { TodoComponentStatefulProps } from "../types/components";
+import { AppProps } from "../types/components";
import { Todos } from "../types/states";
import { setItem } from "../utils/storage";
import { validateState } from "../utils/validateState";
@@ -8,10 +8,7 @@ import TodoForm from "./TodoForm";
import TodoList from "./TodoList";
interface AppContext {}
-const App = function (
- this: AppContext,
- { $target, initialState }: TodoComponentStatefulProps
-) {
+const App = function (this: AppContext, { $target, initialState }: AppProps) {
// ...
initialState = validateState(initialState);
@@ -62,6 +59,6 @@ const App = function (
$target,
initialState,
});
-} as any as { new (props: TodoComponentStatefulProps): AppContext };
+} as any as { new (props: AppProps): AppContext };
export default App;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
index 9e119c4..d2f1b47 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/Header.ts
@@ -1,10 +1,8 @@
import {
+ HeaderProps,
TodoComponentStatelessContext,
- TodoComponentStatelessProps,
} from "../types/components";
-type HeaderProps = TodoComponentStatelessProps<{ text: string }>;
-
const Header = function (
this: TodoComponentStatelessContext,
{ $target, text }: HeaderProps
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
index b57d460..8fd4d98 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoCount.ts
@@ -1,12 +1,12 @@
import {
TodoComponentStatefulContext,
- TodoComponentStatefulProps,
+ TodoCountProps,
} from "../types/components";
import { Todos } from "../types/states";
const TodoCount = function (
this: TodoComponentStatefulContext,
- { $target, initialState }: TodoComponentStatefulProps
+ { $target, initialState }: TodoCountProps
) {
this.state = initialState;
@@ -29,7 +29,7 @@ const TodoCount = function (
this.render();
} as any as {
- new (props: TodoComponentStatefulProps): TodoComponentStatefulContext;
+ new (props: TodoCountProps): TodoComponentStatefulContext;
};
export default TodoCount;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
index b928fe9..bbaa05c 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoForm.ts
@@ -1,12 +1,8 @@
import {
TodoComponentStatelessContext,
- TodoComponentStatelessProps,
+ TodoFormProps,
} from "../types/components";
-type TodoFormProps = TodoComponentStatelessProps<{
- onSubmit: (text: string) => void;
-}>;
-
const TodoForm = function (
this: TodoComponentStatelessContext,
{ $target, onSubmit }: TodoFormProps
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
index ebb5698..0118e2f 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoItem.ts
@@ -1,14 +1,7 @@
import {
TodoComponentStatelessContext,
- TodoComponentStatelessProps,
+ TodoItemProps,
} from "../types/components";
-import { Todo } from "../types/states";
-
-type TodoItemProps = TodoComponentStatelessProps<{
- initialValue: Todo;
- onToggle: (id: string) => void;
- onDelete: (id: string) => void;
-}>;
const TodoItem = function (
this: TodoComponentStatelessContext,
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
index e869784..f0e833c 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/components/TodoList.ts
@@ -1,15 +1,11 @@
import {
TodoComponentStatefulContext,
- TodoComponentStatefulProps,
+ TodoListProps,
} from "../types/components";
import { Todos } from "../types/states";
import { setItem } from "../utils/storage";
import TodoItem from "./TodoItem";
-type TodoListProps = TodoComponentStatefulProps<{
- onToggle: (id: string) => void;
- onDelete: (id: string) => void;
-}>;
const TodoList = function (
this: TodoComponentStatefulContext,
{ initialState, $target, onToggle, onDelete }: TodoListProps
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
index cb3c932..d4160e0 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/types/components.ts
@@ -1,35 +1,46 @@
-import { Todos } from "./states";
+import { Todo, Todos } from "./states";
// 컴포넌트 구조 typing
// 컴포넌트 Context
-interface CoreComponentContext {
- state?: T;
- setState?: (nextState: T) => void;
+
+export type TodoComponentContext = {
+ state?: Todos;
+ setState?: (nextState: Todos) => void;
render: () => void;
-}
-type StatefulComponentContext = {
- [K in keyof CoreComponentContext]-?: CoreComponentContext[K];
};
-type StatelessComponentContext = Omit<
- CoreComponentContext,
+export type TodoComponentStatefulContext = {
+ [K in keyof TodoComponentContext]-?: TodoComponentContext[K];
+};
+
+export type TodoComponentStatelessContext = Omit<
+ TodoComponentContext,
"state" | "setState"
>;
-export type TodoComponentContext = CoreComponentContext;
-export type TodoComponentStatefulContext = StatefulComponentContext;
-export type TodoComponentStatelessContext = StatelessComponentContext;
// 컴포넌트 Props
export interface CoreComponentProps {
$target: HTMLElement;
}
-export interface StatefulComponentProps extends CoreComponentProps {
- initialState: T;
+interface TodoStatefulComponentProps extends CoreComponentProps {
+ initialState: Todos;
+}
+export interface TodoItemProps extends CoreComponentProps {
+ initialValue: Todo;
+ onToggle: (id: string) => void;
+ onDelete: (id: string) => void;
+}
+export interface TodoListProps extends TodoStatefulComponentProps {
+ onToggle: (id: string) => void;
+ onDelete: (id: string) => void;
}
-export type TodoComponentStatefulProps =
- StatefulComponentProps & {
- [K in keyof T]: T[K];
- };
-export type TodoComponentStatelessProps = CoreComponentProps & {
- [K in keyof T]: T[K];
-};
+export interface TodoCountProps extends TodoStatefulComponentProps {}
+
+export interface TodoFormProps extends CoreComponentProps {
+ onSubmit: (text: string) => void;
+}
+
+export interface AppProps extends TodoStatefulComponentProps {}
+export interface HeaderProps extends CoreComponentProps {
+ text: string;
+}
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
index 0c5d1d1..3f77718 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/storage.ts
@@ -1,5 +1,5 @@
import { ERROR_MESSAGES } from "../constants";
-import { Todos } from "../types/components";
+import { Todos } from "../types/states";
export type setStorage = (key: string, value: T) => void;
export type getStorage = (key: string, defaultValue: T) => T;
diff --git a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
index 076d2f0..48089c3 100644
--- a/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
+++ b/yongjae/projects/FEDC5-3_VanillaJS_1/src/utils/validateState.ts
@@ -1,5 +1,5 @@
import { ERROR_MESSAGES } from "../constants";
-import { Todos } from "../types/components";
+import { Todos } from "../types/states";
// todo 상태의 유효검사 함수
export function validateState(state: Todos, origin: Todos = []) {
if (