{"id":4306,"date":"2026-02-15T09:38:15","date_gmt":"2026-02-15T00:38:15","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=4306"},"modified":"2026-02-15T11:48:12","modified_gmt":"2026-02-15T02:48:12","slug":"vitereact-typescript-example1","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/02\/15\/vitereact-typescript-example1\/","title":{"rendered":"[Vite+React]\ud0c0\uc785\uc2a4\ud06c\ub9bd\ud2b8 \uc608\uc81c \/ TypeScript example"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc2a4\ud06c\ub9bd\ud2b8\ub294 \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8 +  \ud0c0\uc785\uc785\ub2c8\ub2e4.<br>TypeScript is JavaScript + types.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\ub294 \uc790\ub3d9\uc73c\ub85c \ud0c0\uc785\uc744 \ucd94\ub860 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \uae30\ub2a5\uc774 \ubd80\uc871\ud560 \uacbd\uc6b0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>JavaScript can automatically infer types, but if the functionality is lacking, errors can occur.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\uc758 \uc790\ub3d9\ucd94\ub860\uc744 \ubcf4\uc644 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>Using types can complement JavaScript&#8217;s automatic inference.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc2a4\ud06c\ub9bd\uc5d0\uc11c \ud0c0\uc785\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ubcc0\uc218, \ud568\uc218 \ud30c\ub77c\ubbf8\ud130\/\ubc18\ud658\uac12, state, props, \uac1d\uccb4\/\ubc30\uc5f4, \uc81c\ub124\ub9ad, \ud0c0\uc785 \ubcc4\uce6d\/\uc778\ud130\ud398\uc774\uc2a4 \ub4f1 \uac70\uc758 \ubaa8\ub4e0 \uac12\uc774 \ub4e4\uc5b4\uac00\ub294 \uacf3\uc5d0 \ud0c0\uc785\uc744 \uc815\uc758\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>When using types in TypeScript, you can define types for almost any value, including variables, function parameters\/return values, state, props, objects\/arrays, generics, type aliases\/interfaces, etc.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \ud0c0\uc785\uc758 \uc0ac\uc6a9\ube48\ub3c4\uac00 \ub192\uc740 \ubd80\ubd84\uc5d0 \ub300\ud55c \uc608\uc81c\uc785\ub2c8\ub2e4.<br>The code below is an example of a frequently used part of the type.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ud504\ub85c\uc81d\ud2b8 \uc0dd\uc131 \/ Create project<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>% npm create vite@latest ReactExample4 --template react-ts\n% cd ReactExample4\n% npm install\n\n# \uc11c\ubc84 \uc2e4\ud589(\uc2e4\ud589 \ud14c\uc2a4\ud2b8) \/ Running the server (running test)\n# Run the server (run test)\n% npm run dev<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \/ Project structure<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>src\/\n\u251c\u2500 types.tsx\n\u251c\u2500 components\/\n\u2502 \u2514\u2500 UserCard.tsx\n\u251c\u2500 App.tsx\n\u251c\u2500 main.tsx<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb1. \uc804\uc5ed \ud0c0\uc785 \uc815\uc758 (<code>src\/types.ts<\/code>)<br>Global type definitions (src\/types.ts)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \uc5ec\ub7ec \ucef4\ud3ec\ub10c\ud2b8\uc5d0\uc11c \uacf5\uc720\ud560 \ud0c0\uc785 \uc815\uc758\nexport type Todo = {\n  id: number;\n  text: string;\n  completed: boolean;\n};<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb2. Props \ud0c0\uc785 \uc9c0\uc815 (<code>src\/components\/UserCard.tsx<\/code>)<br>Specifying Prop types (src\/components\/UserCard.tsx)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\n\ntype UserCardProps = {\n  name: string;\n  age?: number; \/\/ \uc120\ud0dd\uc801 props \/ optional props\n};\n\nconst UserCard: React.FC&lt;UserCardProps&gt; = ({ name, age }) =&gt; {\n  return (\n    &lt;div style={{ border: \"1px solid gray\", padding: \"10px\", margin: \"5px\" }}&gt;\n      &lt;h2&gt;{name}&lt;\/h2&gt;\n      {age &amp;&amp; &lt;p&gt;Age: {age}&lt;\/p&gt;}\n    &lt;\/div&gt;\n  );\n};\n\nexport default UserCard;\n<\/code><\/pre>\n\n\n\n<p>\u2b50\ufe0f React.FC&lt;UserCardProps><\/p>\n\n\n\n<p>\u2714\ufe0f React.FC\ub97c \uc0ac\uc6a9\ud558\uba74 children porps\uac00 \uc790\ub3d9 \ud3ec\ud568\ub429\ub2c8\ub2e4.(\ud0c0\uc785\uc5d0 children\uc744 \uc815\uc758\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub429\ub2c8\ub2e4.)<br>React.FC automatically includes children types (you don&#8217;t need to define children in your types).<\/p>\n\n\n\n<p>\u2714\ufe0f \ud544\uc694\ud55c \uacbd\uc6b0 \uaebc\ub0b4\uc11c \uc0ac\uc6a9 \ud560 \uc218 \uc788\uace0 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc744 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<br>You can take it out and use it if you need to, or you can leave it out if you don&#8217;t.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const UserCard: React.FC&lt;UserCardProps&gt; = ({ name, age, children }) =&gt; {\n  return (\n    &lt;div style={{ border: \"1px solid gray\", padding: \"10px\", margin: \"5px\" }}&gt;\n      &lt;h2&gt;{name}&lt;\/h2&gt;\n      {age &amp;&amp; &lt;p&gt;Age: {age}&lt;\/p&gt;}\n      &lt;div&gt;{children}&lt;\/div&gt; {\/* \uc5ec\uae30\uc11c children \ucd9c\ub825 *\/}\n    &lt;\/div&gt;\n  );\n};<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f children\uc744 \uc790\ub3d9\uc73c\ub85c \ud3ec\ud568\ud558\uc9c0 \uc54a\uc744 \uacbd\uc6b0 \uc544\ub798\ucc98\ub7fc \uc0ac\uc6a9 \ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<br>If you don&#8217;t want to automatically include children, you can use it like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type UserCardProps = {\n  name: string;\n  age?: number;\n};\n\nfunction UserCard({ name, age }: UserCardProps) {\n  return (\n    &lt;div&gt;\n      &lt;h2&gt;{name}&lt;\/h2&gt;\n      {age &amp;&amp; &lt;p&gt;Age: {age}&lt;\/p&gt;}\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb3. State \ud0c0\uc785 \uc9c0\uc815 + \ud568\uc218 \ud0c0\uc785 \uc9c0\uc815 (<code>src\/App.tsx<\/code>)<br>State type specification + function type specification (src\/App.tsx)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React, { useState } from \"react\";\nimport UserCard from \".\/components\/UserCard\";\n<strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\">import type { Todo } from \".\/types\";<\/mark><\/strong>\n\n\/\/ \ud568\uc218 \ud0c0\uc785 \uc9c0\uc815: string\uc744 \ubc1b\uc544 string\uc744 \ubc18\ud658\n\/\/ Function type specification: takes a string and returns a string\nfunction greet(name: string)<strong>: <\/strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\"><strong>string<\/strong> <\/mark>{\n  return `Hello, ${name}!`;\n}\n\nfunction App() {\n  \/\/ State \ud0c0\uc785 \uc9c0\uc815\n\/\/ Specify State type\n  <strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\">const &#91;todos, setTodos] = <\/mark><\/strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\"><strong>useState&lt;Todo&#91;]&gt;<\/strong><\/mark>(&#91;\n    { id: 1, text: \"Learn Vite\", completed: false },\n    { id: 2, text: \"Practice TypeScript\", completed: true },\n  ]);\n  \/\/ \ub9cc\uc57d toggleTodo(3)\uc744 \ud638\ucd9c\ud558\uba74, id\uac00 3\uc778 todo\ub97c \ucc3e\uc544\uc11c completed \uac12\uc744 \ubc18\uc804\uc2dc\ud0b5\ub2c8\ub2e4.\n  \/\/ If you call toggleTodo(3), it will find the todo with id 3 and invert its completed value.\n  const toggleTodo = (id: number) =&gt; {\n    setTodos((prev) =&gt;\n      prev.map((todo) =&gt;\n        todo.id === id ? { ...todo, completed: !todo.completed } : todo\n      )\n    );\n  };\n\n  return (\n    &lt;div style={{ padding: \"20px\" }}&gt;\n      &lt;h3&gt;Vite + React + TypeScript Example&lt;\/h3&gt;\n      &lt;p&gt;<mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\"><strong>{greet(\"Johnny\")}<\/strong><\/mark>&lt;\/p&gt;\n\n      &lt;h2&gt;User Cards&lt;\/h2&gt;\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\"><strong>      &lt;UserCard name=\"Alice\" age={25} \/&gt;\n      &lt;UserCard name=\"Bob\" \/&gt;<\/strong><\/mark>\n\n      &lt;h2&gt;Todo List&lt;\/h2&gt;\n      &lt;ul&gt;\n        {todos.map((todo) =&gt; (\n          &lt;li\n            key={todo.id}\n            style={<strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#551ea9\" class=\"has-inline-color\">{\n              textDecoration: todo.completed ? \"line-through\" : \"none\",\n              cursor: \"pointer\",\n            }<\/mark><\/strong>}\n            onClick={() =&gt; toggleTodo(todo.id)}\n          &gt;\n            <mark style=\"background-color:rgba(0, 0, 0, 0);color:#541da5\" class=\"has-inline-color\"><strong>{todo.text}<\/strong><\/mark>\n          &lt;\/li&gt;\n        ))}\n      &lt;\/ul&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>\u2b50\ufe0f \uae30\uc874 \uc0c1\ud0dc\ubc18\uc804 \/ Inversion of existing state<\/p>\n\n\n\n<p>\u2714\ufe0fprev.map(\u2026)<\/p>\n\n\n\n<p>&#8212; <code>prev<\/code>\ub294 \uc774\uc804 <code>todos<\/code> \ubc30\uc5f4\uc785\ub2c8\ub2e4.<br>prev is the previous todos array.<\/p>\n\n\n\n<p>&#8212; <code>map<\/code>\uc744 \uc0ac\uc6a9\ud574\uc11c \ubc30\uc5f4\uc744 \uc21c\ud68c\ud558\uba74\uc11c, <code>id<\/code>\uac00 \uc77c\uce58\ud558\ub294 <code>todo<\/code>\ub9cc <code>completed<\/code> \uac12\uc744 \ubc18\uc804\uc2dc\ud0b5\ub2c8\ub2e4.<br>Using map, we iterate through the array and invert the completed value only for todos with matching id.<\/p>\n\n\n\n<p>&#8212; <code>{ ...todo, completed: !todo.completed }<\/code> \uc774 \uad6c\ubb38\uc740 \uae30\uc874 todo \uac1d\uccb4\ub97c \ubcf5\uc0ac\ud55c \ub4a4, <code>completed<\/code> \uc18d\uc131\ub9cc \ubc18\uc804\uc2dc\ucf1c\uc11c \uc0c8\ub85c\uc6b4 \uac1d\uccb4\ub97c \ubc18\ud658\ud558\ub294 \ubc29\uc2dd\uc785\ub2c8\ub2e4.<br>{ \u2026todo, completed: !todo.completed } This syntax copies the existing todo object and returns a new object with only the completed property reversed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  const toggleTodo = (id: number) =&gt; {\n    setTodos((prev) =&gt;\n      prev.map((todo) =&gt;\n        todo.id === id ? { ...todo, completed: !todo.completed } : todo\n      )\n    );\n  };<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb4. \uc9c4\uc785 \ud30c\uc77c (<code>src\/main.tsx<\/code>)<br>Entry file (src\/main.tsx)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import React from \"react\";\nimport ReactDOM from \"react-dom\/client\";\nimport App from \".\/App\";\nimport \".\/index.css\";\n\nReactDOM.createRoot(document.getElementById(\"root\")!).render(\n  &lt;React.StrictMode&gt;\n    &lt;App \/&gt;\n  &lt;\/React.StrictMode&gt;\n);\n<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb5.\uc2a4\ud06c\ub9b0 \uc0f7 \/ ScreenShot <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"881\" height=\"1024\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-881x1024.png\" alt=\"\" class=\"wp-image-4361\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-881x1024.png 881w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-258x300.png 258w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-768x893.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-400x465.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types-800x930.png 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/sc-react-types.png 936w\" sizes=\"auto, (max-width: 881px) 100vw, 881px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc2a4\ud06c\ub9bd\ud2b8\ub294 \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8 + \ud0c0\uc785\uc785\ub2c8\ub2e4.TypeScript is JavaScript + types. \ud83d\udc49\ud83c\udffb \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\ub294 \uc790\ub3d9\uc73c\ub85c \ud0c0\uc785\uc744 \ucd94\ub860 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \uae30\ub2a5\uc774 \ubd80\uc871\ud560 \uacbd\uc6b0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.JavaScript can automatically infer types, but if the functionality is lacking, errors can occur. \ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\uc758 \uc790\ub3d9\ucd94\ub860\uc744 \ubcf4\uc644 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.Using types can complement JavaScript&#8217;s automatic inference. \ud83d\udc49\ud83c\udffb \ud0c0\uc785\uc2a4\ud06c\ub9bd\uc5d0\uc11c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,1,7],"tags":[],"class_list":["post-4306","post","type-post","status-publish","format-standard","hentry","category-react","category-uncategorized","category-website","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=4306"}],"version-history":[{"count":54,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4306\/revisions"}],"predecessor-version":[{"id":4363,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4306\/revisions\/4363"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=4306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=4306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=4306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}