You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue组件传入函数作为Props时TypeScript编译异常

Vue组件Props允许函数返回值的类型检查逻辑及禁用方案

为什么会出现这种情况

这是Vue为适配模板语法灵活性特意做的设计。在Vue模板里用:prop绑定值时,支持两种写法:直接传值,或者传一个能返回对应值的函数(常见于动态计算、列表渲染这类场景)。为了让TypeScript兼容这种语法,Vue的类型定义会自动给每个Props的类型加上函数返回值的兼容——也就是把原本的T扩展成T | (() => T)。

所以你传入() => number[]不会报错,但如果函数返回string[]就会触发类型错误,本质是TS在检查函数返回值是否匹配原Props类型,只是允许了函数作为传入形式。

怎么禁用这个特性

如果不需要这种兼容逻辑,可以通过以下两种方式解决:

1. 直接用Exclude排除函数类型

在子组件定义Props时,手动用TypeScript的Exclude工具类型去掉函数类型:

<script setup lang="ts">
defineProps<{
  isTsError: Exclude<number[], () => number[]>
}>()
</script>

2. 封装严格类型的Props定义工具

可以写一个全局工具函数,强制Props只接受原始类型,拒绝函数传入:

// src/utils/defineStrictProps.ts
import { defineProps } from 'vue'

// 排除所有函数类型
type StrictProp<T> = Exclude<T, () => unknown>

export function defineStrictProps<T extends Record<string, unknown>>() {
  return defineProps<T>() as { [K in keyof T]: StrictProp<T[K]> }
}

之后在组件里替换defineProps使用:

<script setup lang="ts">
import { defineStrictProps } from '@/utils/defineStrictProps'

defineStrictProps<{
  isTsError: number[]
}>()
</script>

额外提醒

禁用这个特性后,模板里原本写:prop="() => someValue"的地方会报错,建议改成直接传值或者用computed包裹。比如用Pinia getter时,直接传store.someGetter或者computed(() => store.someGetter),不要把getter函数本身传进去,这样既符合类型要求,也能避免潜在的bug。

内容的提问来源于stack exchange,提问作者FrozenKiwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:00:04