{"id":488,"date":"2025-12-05T10:40:12","date_gmt":"2025-12-05T02:40:12","guid":{"rendered":"https:\/\/www.52runoob.com\/?p=488"},"modified":"2025-12-05T10:40:12","modified_gmt":"2025-12-05T02:40:12","slug":"vue-3-typescript-%e6%8e%a5%e5%8f%a3interface%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b%e8%af%a6%e8%a7%a3","status":"publish","type":"post","link":"https:\/\/www.52runoob.com\/index.php\/2025\/12\/05\/vue-3-typescript-%e6%8e%a5%e5%8f%a3interface%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b%e8%af%a6%e8%a7%a3\/","title":{"rendered":"Vue\u00a03\u00a0TypeScript\u00a0\u63a5\u53e3Interface\u4f7f\u7528\u793a\u4f8b\u8be6\u89e3"},"content":{"rendered":"\n<p>\u4e0b\u9762\u7ed9\u4f60\u4e00\u4efd <strong>Vue 3 + TypeScript \u4e0b\u63a5\u53e3 (<code>interface<\/code>) \u4f7f\u7528\u7684\u8be6\u89e3\u793a\u4f8b<\/strong>\uff0c\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u6db5\u76d6\u7ec4\u4ef6 props\u3001\u54cd\u5e94\u5f0f\u6570\u636e\u3001\u51fd\u6570\u7c7b\u578b\u3001\u6cdb\u578b\u4ee5\u53ca\u4e0e Vue \u7ec4\u5408\u5f0f API \u7684\u7ed3\u5408\u5b9e\u8df5\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1\ufe0f\u20e3 \u57fa\u7840\u63a5\u53e3\u4f7f\u7528<\/h1>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ \u5b9a\u4e49\u4e00\u4e2a\u63a5\u53e3\ninterface User {\n  id: number\n  name: string\n  age?: number \/\/ \u53ef\u9009\u5c5e\u6027\n}\n\n\/\/ \u4f7f\u7528\u63a5\u53e3\u58f0\u660e\u53d8\u91cf\nconst user1: User = {\n  id: 1,\n  name: &#039;Alice&#039;,\n}\n\n\/\/ \u9519\u8bef\u793a\u8303\uff1a\u7f3a\u5c11 id\n\/\/ const user2: User = { name: &#039;Bob&#039; } \/\/ \u274c TS \u4f1a\u62a5\u9519\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2\ufe0f\u20e3 \u63a5\u53e3\u4e0e\u51fd\u6570\u7c7b\u578b<\/h1>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface Greeter {\n  (name: string): string\n}\n\nconst greet: Greeter = (name) =&gt; {\n  return `Hello, ${name}!`\n}\n\nconsole.log(greet(&#039;Alice&#039;)) \/\/ Hello, Alice!\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3\ufe0f\u20e3 \u63a5\u53e3\u7ee7\u627f\uff08Extends\uff09<\/h1>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface Person {\n  name: string\n  age: number\n}\n\ninterface Employee extends Person {\n  employeeId: string\n}\n\nconst emp: Employee = {\n  name: &#039;Tom&#039;,\n  age: 25,\n  employeeId: &#039;E1001&#039;\n}\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4\ufe0f\u20e3 Vue 3 + TypeScript \u4f7f\u7528\u63a5\u53e3\u793a\u4f8b<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 \u5b9a\u4e49 Props \u63a5\u53e3<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ UserCard.vue\n&amp;lt;script lang=&quot;ts&quot; setup&gt;\nimport { defineProps } from &#039;vue&#039;\n\n\/\/ \u5b9a\u4e49\u63a5\u53e3\ninterface User {\n  id: number\n  name: string\n  age?: number\n}\n\n\/\/ \u4f7f\u7528\u63a5\u53e3\u5b9a\u4e49 props\nconst props = defineProps&amp;lt;{\n  user: User\n  showAge?: boolean\n}&gt;()\n&amp;lt;\/script&gt;\n\n&amp;lt;template&gt;\n  &amp;lt;div&gt;\n    &amp;lt;p&gt;\u540d\u5b57: {{ props.user.name }}&amp;lt;\/p&gt;\n    &amp;lt;p v-if=&quot;props.showAge&quot;&gt;\u5e74\u9f84: {{ props.user.age }}&amp;lt;\/p&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/template&gt;\n\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u2705 \u597d\u5904\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>props \u6709\u7c7b\u578b\u7ea6\u675f<\/li>\n\n\n\n<li>\u652f\u6301\u53ef\u9009\u5c5e\u6027<\/li>\n\n\n\n<li>\u7f16\u8f91\u5668\u63d0\u793a\u5f3a\u5927<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 \u5b9a\u4e49\u54cd\u5e94\u5f0f\u5bf9\u8c61<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;script lang=&quot;ts&quot; setup&gt;\nimport { reactive } from &#039;vue&#039;\n\ninterface Product {\n  id: number\n  name: string\n  price: number\n}\n\nconst product = reactive&amp;lt;Product&gt;({\n  id: 1,\n  name: &#039;MacBook Pro&#039;,\n  price: 1999\n})\n\n\/\/ \u4fee\u6539\u5c5e\u6027\nproduct.price = 1899\n&amp;lt;\/script&gt;\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4.3 \u63a5\u53e3\u5b9a\u4e49\u51fd\u6570\u53c2\u6570<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface Calculator {\n  (a: number, b: number): number\n}\n\nconst add: Calculator = (a, b) =&gt; a + b\nconst multiply: Calculator = (a, b) =&gt; a * b\n\n<\/pre><\/div>\n\n\n<p>\u5728 Vue \u4e8b\u4ef6\u4e2d\u4f7f\u7528\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nconst handleClick = (fn: Calculator) =&gt; {\n  console.log(fn(2, 3))\n}\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5\ufe0f\u20e3 \u63a5\u53e3\u4e0e\u6cdb\u578b\u7ed3\u5408<\/h1>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface ApiResponse&amp;lt;T&gt; {\n  code: number\n  data: T\n  message: string\n}\n\n\/\/ \u793a\u4f8b\u63a5\u53e3\u8fd4\u56de User \u6570\u636e\nconst res: ApiResponse&amp;lt;User&gt; = {\n  code: 200,\n  data: { id: 1, name: &#039;Alice&#039; },\n  message: &#039;ok&#039;\n}\n\n<\/pre><\/div>\n\n\n<p>\u5728 Vue \u7ec4\u4ef6\u4e2d\u53ef\u76f4\u63a5\u4f7f\u7528\u6cdb\u578b\uff1a<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nimport { ref } from &#039;vue&#039;\n\nconst response = ref&amp;lt;ApiResponse&amp;lt;User&gt;&gt;({\n  code: 0,\n  data: { id: 0, name: &#039;&#039; },\n  message: &#039;&#039;\n})\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6\ufe0f\u20e3 \u9ad8\u7ea7\u63a5\u53e3\uff1a\u7d22\u5f15\u7b7e\u540d &amp; \u4ea4\u53c9\u7c7b\u578b<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">6.1 \u7d22\u5f15\u7b7e\u540d<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface StringMap {\n  &#x5B;key: string]: string\n}\n\nconst obj: StringMap = {\n  name: &#039;Alice&#039;,\n  city: &#039;Beijing&#039;\n}\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6.2 \u4ea4\u53c9\u7c7b\u578b\uff08\u7ec4\u5408\u591a\u4e2a\u63a5\u53e3\uff09<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ninterface A { a: number }\ninterface B { b: string }\n\ntype C = A &amp;amp; B\n\nconst objC: C = { a: 10, b: &#039;Hello&#039; }\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7\ufe0f\u20e3 Vue 3 \u7ec4\u5408\u5f0f API \u7efc\u5408\u793a\u4f8b<\/h1>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&amp;lt;script lang=&quot;ts&quot; setup&gt;\nimport { reactive, ref } from &#039;vue&#039;\n\ninterface Todo {\n  id: number\n  title: string\n  done: boolean\n}\n\nconst todos = reactive&amp;lt;Todo&#x5B;]&gt;(&#x5B;\n  { id: 1, title: &#039;Learn Vue 3&#039;, done: false },\n  { id: 2, title: &#039;Learn TypeScript&#039;, done: true }\n])\n\nconst newTodo = ref&amp;lt;Todo&gt;({ id: 3, title: &#039;Write demo&#039;, done: false })\n\nconst addTodo = () =&gt; {\n  todos.push({ ...newTodo.value })\n  newTodo.value.title = &#039;&#039;\n}\n\nconst toggleTodo = (todo: Todo) =&gt; {\n  todo.done = !todo.done\n}\n&amp;lt;\/script&gt;\n\n&amp;lt;template&gt;\n  &amp;lt;div&gt;\n    &amp;lt;ul&gt;\n      &amp;lt;li v-for=&quot;todo in todos&quot; :key=&quot;todo.id&quot;&gt;\n        &amp;lt;input type=&quot;checkbox&quot; v-model=&quot;todo.done&quot; @change=&quot;toggleTodo(todo)&quot; \/&gt;\n        {{ todo.title }} - {{ todo.done ? &#039;\u5b8c\u6210&#039; : &#039;\u672a\u5b8c\u6210&#039; }}\n      &amp;lt;\/li&gt;\n    &amp;lt;\/ul&gt;\n\n    &amp;lt;input v-model=&quot;newTodo.title&quot; placeholder=&quot;\u65b0\u4efb\u52a1&quot; \/&gt;\n    &amp;lt;button @click=&quot;addTodo&quot;&gt;\u6dfb\u52a0&amp;lt;\/button&gt;\n  &amp;lt;\/div&gt;\n&amp;lt;\/template&gt;\n\n<\/pre><\/div>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u2705 \u7279\u70b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>todo \u7c7b\u578b\u5f3a\u7ea6\u675f<\/li>\n\n\n\n<li>\u65b0\u589e\u3001\u4fee\u6539\u90fd\u81ea\u52a8\u63d0\u793a\u7c7b\u578b<\/li>\n\n\n\n<li>Vue \u54cd\u5e94\u5f0f\u548c TS \u7c7b\u578b\u7ed3\u5408\u5b8c\u7f8e<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8\ufe0f\u20e3 \u603b\u7ed3<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>interface vs type<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>interface \u53ef\u4ee5\u58f0\u660e\u5bf9\u8c61\u3001\u51fd\u6570\u7c7b\u578b\u3001\u7ee7\u627f\u3001\u5408\u5e76\u58f0\u660e<\/li>\n\n\n\n<li>type \u66f4\u9002\u5408\u8054\u5408\u7c7b\u578b\u3001\u4ea4\u53c9\u7c7b\u578b\u3001\u57fa\u672c\u7c7b\u578b\u522b\u540d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Vue 3 + TS \u6700\u5e38\u7528\u573a\u666f\uff1a\n<ul class=\"wp-block-list\">\n<li><code>defineProps&lt;Interface>()<\/code><\/li>\n\n\n\n<li><code>reactive&lt;Interface>()<\/code> \/ <code>ref&lt;Interface>()<\/code><\/li>\n\n\n\n<li>\u51fd\u6570\u53c2\u6570\u7c7b\u578b<\/li>\n\n\n\n<li>API \u8fd4\u56de\u503c\u6cdb\u578b\u7c7b\u578b<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u4f18\u52bf\uff1a\n<ul class=\"wp-block-list\">\n<li>\u4ee3\u7801\u53ef\u7ef4\u62a4\u6027\u5f3a<\/li>\n\n\n\n<li>\u7f16\u8f91\u5668\u63d0\u793a\u5b8c\u5584<\/li>\n\n\n\n<li>\u7ec4\u4ef6 props \/ \u4e8b\u4ef6 \/\u72b6\u6001\u90fd\u6709\u7c7b\u578b\u5b89\u5168<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0b\u9762\u7ed9\u4f60\u4e00\u4efd Vue 3 + TypeScript \u4e0b\u63a5\u53e3 (interface&#8230; <a class=\"more-link\" href=\"https:\/\/www.52runoob.com\/index.php\/2025\/12\/05\/vue-3-typescript-%e6%8e%a5%e5%8f%a3interface%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b%e8%af%a6%e8%a7%a3\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49],"tags":[],"class_list":["post-488","post","type-post","status-publish","format-standard","hentry","category-javascript"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/488","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/comments?post=488"}],"version-history":[{"count":1,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/488\/revisions"}],"predecessor-version":[{"id":489,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/posts\/488\/revisions\/489"}],"wp:attachment":[{"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/media?parent=488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/categories?post=488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.52runoob.com\/index.php\/wp-json\/wp\/v2\/tags?post=488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}