为什么我感觉 Vue 3 TypeScript 还是不行?
68 个回答
给 Vue 提过几个类型的 PR。说一些个人的看法。
- 我觉得 props 的问题很大程度上是兼容性包袱导致的,在 Vue 组件的 prop resolve 的过程里,如果没有大量编写经验其实很难记清楚每种配置会 resolve 什么值。同时这些动态 resolve prop 的过程也对类型的编写造成了很多麻烦,即使在现在的版本,setup 函数中 props 的静态类型和 runtime 的实际表现都有不小的偏差。如果未来这些不一致可以全部修复的话倒也不算什么大问题了。详见:
2. 定义共有 props 组件我觉得问题不是很大,只是相比于 React 在 interface 的层面就能共享,Vue 目前必须通过展开运算符才能解决。
// 通过下面的方式产生共享的 props,利用 ExtractPropTypes 导出类型
const commonProps = {
c: Boolean
} as const
const AProps = {
...commonProps,
a: Boolean
} as const
const BProps = {
...commonProps,
b: Boolean
} as const
我想提一下的是 ExtractPropTypes 的另一个问题,这个工具类型提取出来的其实是用于 setup 函数的 props 而不是外界传入的 props,这实际上对于类型的使用造成了一些阻碍。在 prop 没有 required 的情况下需要使用
Partial<ExtractPropTypes<typeof xxxProps>>
才能给出实际外部的 props 的类型。
3. 针对于组件 props 的泛型,目前似乎没啥好办法,我也很头大,只能采取比泛型更松的类型约束。泛型类型对于业务组件的编写可能不算特别常用,但是对于底层组件的编写其实非常重要。详见:
4. 取缔 SFC 组件有点过于激进了,有点因噎废食的感觉。如果工具链能成熟多数场景下是可以使用 SFC 来编写的,既维持模板的优点也带有类型检查。当然前提是工具链能成熟,包含 vscode 的插件、类似 tsc --noEmit 的命令行类型检查,正确的 dts 文件生成。在年初的时候我尝试过 vuedx、volar,vuedx 会让我的 vscode 卡死,volar 总有类型提示存在问题,发现不太能适应我的开发场景。但是 ts 不能不上,最后我把一个 .vue 的组件库用 .tsx 重写了= =...
5. slots 的位置确实有放到 props 的可能,毕竟它的机制和 render props 非常像,但是我个人觉得放到 prop 里面会导致 tsx 更加难看,因为 vue3 的组件全量使用了函数 slot,不允许数组作为组件 children,在嵌套组件时候和别的 prop 会混起来,这两种风格可能大家各有喜好:
// <A><B><C /></B></A>
// render props
{...aProps}
defaultSlot={() => (
{...bProps}
defaultSlot={() => <C {...cProps} />}
// children
// 我个人觉得下面好一些
<A {...aProps}>
default: () => (
<B {...bProps}>
default: () => <C {...cProps} />