省流總結:
defineProps
的泛型能力,來直接推導第三方組件的 props 類型
引入第三方庫的類型,并直接在 <script setup>
中作為 props 使用。這種類型一般是復雜泛型(包含聯合類型、可選屬性、交叉類型、條件類型等)。
特性 | Vue 3.2 | Vue 3.5(或 Vue 3.3+) |
---|---|---|
泛型類型識別 | ? 可識別 | ? 可識別 |
defineProps<泛型>() 支持 | ? 支持,但弱 | ? 支持完整 |
模板中類型提示(TS 提示) | ? 無提示或不完整 | ? 完整提示 |
第三方庫類型支持(復雜類型) | ?? 需要手動檢查 | ? 可放心使用 |
問題:同一句代碼,在不同版本中的差異。
在vue3.2出現了報錯,即不支持第三方的類型;在vue3.5可以直接使用,不存在報錯。
報錯語句:
import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'
defineProps<FontAwesomeIconProps>()
?vue3.2中的?報錯內容:[@vue/compiler-sfc] type argument passed to defineProps() must be a literal type, or a reference to an interface or literal type.
?
?分析 —— 不同版本對復雜泛型的支持情況:
import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'
defineProps<FontAwesomeIconProps>()
使用了 defineProps
的泛型能力,來直接推導第三方組件的 props 類型
引入第三方庫的類型(FontAwesomeIconProps
),并直接在 <script setup>
中作為 props 使用。這種類型一般是復雜泛型(包含聯合類型、可選屬性、交叉類型、條件類型等)。
🧩 Vue 3.2 的支持情況
? 可以使用,但存在以下限制:
-
類型可以正常識別,不會報錯;
-
模板中不會獲得完整的類型提示,例如
icon
、spin
這些 props,VSCode 無法自動補全或做類型檢查; -
類型系統在
<script setup>
中并不會很好地將defineProps<T>()
的泛型映射到template
; -
@vue/compiler-sfc
和vue-tsc
對defineProps<T>()
泛型的推導能力有限。
? 示例效果(Vue 3.2)
<script setup lang="ts">
import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'
const props = defineProps<FontAwesomeIconProps>()// 這里 props 有類型提示,但 template 中沒有
</script><template><FontAwesomeIcon :icon="icon" /> <!-- ? icon 無提示,甚至報錯 -->
</template>
🧩 Vue 3.5 的支持情況(或 Vue 3.3+)
? 支持非常完整
-
defineProps<FontAwesomeIconProps>()
會被完全推導; -
VSCode / Volar 插件會在
<template>
中提供準確的類型提示; -
即使
FontAwesomeIconProps
是復雜類型(比如嵌套、聯合、交叉),也能推導成功; -
和
<script setup generic>
可以配合使用,如果你需要泛型組件;
? 示例效果(Vue 3.5)
<script setup lang="ts">
import type { FontAwesomeIconProps } from '@fortawesome/vue-fontawesome'const props = defineProps<FontAwesomeIconProps>()
</script><template><FontAwesomeIcon :icon="props.icon" :spin="props.spin" /> <!-- ? 全都有類型提示 -->
</template>
或者直接在模板中使用:
<template><FontAwesomeIcon v-bind="props" /> <!-- ? 類型也能傳遞 -->
</template>
? 總結對比
特性 | Vue 3.2 | Vue 3.5(或 Vue 3.3+) |
---|---|---|
泛型類型識別 | ? 可識別 | ? 可識別 |
defineProps<泛型>() 支持 | ? 支持,但弱 | ? 支持完整 |
模板中類型提示(TS 提示) | ? 無提示或不完整 | ? 完整提示 |
第三方庫類型支持(復雜類型) | ?? 需要手動檢查 | ? 可放心使用 |
建議:
如果你正在使用
FontAwesomeIconProps
這種復雜泛型作為defineProps
的泛型參數,并希望:
保證 props 類型安全
在
<template>
中獲得提示、補全更好維護和復用
請升級至 Vue 3.3 或 3.5,搭配 TypeScript 5.x 和最新的 Volar 插件,體驗會好很多。
?vue3.2中引入第三方類型,如何解決?
創建獨立的別名,并復制拷貝所參考的第三方庫的屬性。
將原先的寫法(注釋部分),改成 引入創建的別名
?即可成功顯示!