You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(I'm sure I saw this mentioned somewhere before, but I can't find any issue nor discussion about it. Apologies if it's a dupe.)
For Typescript users, script setup needs a defineSlots macro to create strongly typed slots.
The problem is that today the code generated by script setup creates TS compilation errors.
The following template creates an error Binding element 'ok' implicitly has an 'any' type.
(You have the same error even if you don't destructure the slot value.)
A small post-scriptum:
I have build errors when the consuming template is a script setup component.
How the component itself is declared seems irrelevant, so that probably means a slots: { ... } addition to classical <script> would keep everything consistent.
I don't know since when, but today I noticed that Volar is able to type slots that are inside components defined by script setup, when they're used in the same project.
That's super cool and a great QoL improvement ✨
It would be super-duper awesome if there was a way to couple that Volar inferrence with a way to make props/slots generic.
I put one real-life example of what it could achieve in this discussion: vuejs/rfcs#334 (comment)
I'm curious what is the real benefit of type checking generated code here - vue-tsc can type check *.vue files directly so you'd preferably use that - which works on your source code providing more accurate error locations. Then you'd use esbuild or transpile-only mode of TS for faster builds. Am I missing something?
I opened this when my slot was implicitly typed as any in IDE.
Now I think this was because the component providing the slot was a script-classic, as it seems that script-setup is inferred by Volar / vue-tsc.
There's no need for manually declaring defineSlots if they can be automatically inferred.
Maybe this issue should have been that a slot: { default: ... } would be welcome in script-classic? Or was my slot implicitly any for a different reason at all? I could have been confused, this is all still experimental to me.
A few extra thoughts / considerations
(1) I'm building with TS not Esbuild, mainly because of const enums. Speed is always good but for production build is not the top priority. Doing 2 TS passes (one with vue-tsc then regular build with TS) is a bit overkill, I opened this discussion about some possible solutions: johnsoncodehk/vue-tsc#48
(2) I am curious how this will all turn out with generic components, which would be a complex, albeit much needed, addition.
For example, if you have a component that provides a slot value only one of its props is filled or has a specific type.
Consider a kind of Form component, that injects a validation object iff its rules property is set:
<template><form><slot:val="val" /></form></template><scriptsetup>// Not sure what the syntax in script setup would be...defineGeneric<Mextendsobject,RextendsRules<M>|undefined>();defineProps<{model: M,rules?: R}>();// This is injected in slot, its type should be Validation if rules props is not undefined, otherwise it's undefined.constval: RextendsRules<M> ? Validation<M,R> : undefined;
</script>
It can all be modelled by TS type system, but when you use the component in a template, I have no idea if it would even be possible to infer the right types!
<!--Here we need to infer:M: { name: string }R: { name: required }So TS can then:- Validate R satisfies Rules<M>- Type val as `Validation<M, R>` (not undefined)--><my-form:model="{ name: 'first' }" :rules="{ name: required }" v-slot="{ val }" /><!--This time we should infer:R: undefinedThen val is `undefined` and trying to use it will result in a compilation error.--><my-form:model="{ name: 'first' }" v-slot="{ val }" />
If the remaining utility is only related to generic components, I think it would be better discussed as part of the generic components proposal. So closing this one here.
If the remaining utility is only related to generic components, I think it would be better discussed as part of the generic components proposal. So closing this one here.
I also find this feature useful when I have slots in child components and would like to define them in the Enclosing Component. I don't know any solution for this.
Activity
[-]defineSlot for script setup[/-][+]defineSlots for script setup[/+]jods4 commentedon Jul 9, 2021
A small post-scriptum:
I have build errors when the consuming template is a script setup component.
How the component itself is declared seems irrelevant, so that probably means a
slots: { ... }addition to classical<script>would keep everything consistent.jods4 commentedon Jul 13, 2021
I don't know since when, but today I noticed that Volar is able to type slots that are inside components defined by
script setup, when they're used in the same project.That's super cool and a great QoL improvement ✨
It would be super-duper awesome if there was a way to couple that Volar inferrence with a way to make props/slots generic.
I put one real-life example of what it could achieve in this discussion:
vuejs/rfcs#334 (comment)
yyx990803 commentedon Jul 13, 2021
I'm curious what is the real benefit of type checking generated code here -
vue-tsccan type check*.vuefiles directly so you'd preferably use that - which works on your source code providing more accurate error locations. Then you'd useesbuildor transpile-only mode of TS for faster builds. Am I missing something?jods4 commentedon Jul 14, 2021
Yes, I agree.
I opened this when my slot was implicitly typed as
anyin IDE.Now I think this was because the component providing the slot was a script-classic, as it seems that script-setup is inferred by Volar / vue-tsc.
There's no need for manually declaring
defineSlotsif they can be automatically inferred.Maybe this issue should have been that a
slot: { default: ... }would be welcome in script-classic? Or was my slot implicitlyanyfor a different reason at all? I could have been confused, this is all still experimental to me.A few extra thoughts / considerations
(1) I'm building with TS not Esbuild, mainly because of const enums. Speed is always good but for production build is not the top priority. Doing 2 TS passes (one with
vue-tscthen regular build with TS) is a bit overkill, I opened this discussion about some possible solutions: johnsoncodehk/vue-tsc#48(2) I am curious how this will all turn out with generic components, which would be a complex, albeit much needed, addition.
For example, if you have a component that provides a slot value only one of its props is filled or has a specific type.
Consider a kind of Form component, that injects a
validationobject iff itsrulesproperty is set:It can all be modelled by TS type system, but when you use the component in a template, I have no idea if it would even be possible to infer the right types!
yyx990803 commentedon Jul 14, 2021
If the remaining utility is only related to generic components, I think it would be better discussed as part of the generic components proposal. So closing this one here.
ccqgithub commentedon Apr 10, 2022
@yyx990803 如果使用volar开发,现在项目中能有scopedSlots props的类型提示,但是貌似是结合模版解析提示的。
但是如果构建一个第三方组件库,
.vue文件会编译成 js 文件,这时候会丢失slots的类型信息(因为现在的defineComponent里面没有slots的类型,所以生成的.d.ts文件貌似不能保留slots 的类型?),引用这类组件库就得不到scopedSlots props的类型提示。所以在现有的defineComponents里加入slots类型变量,以及
script setup里加入defineSlots好像有必要?或者可以在现有的
useSlots上加上泛型?paya-cz commentedon Apr 27, 2022
This should be reopened. I use the latest Volar yet I do not have any type interference for slot props. I get type
anyjust like the OP did.MueckeMa commentedon Nov 29, 2022
I also find this feature useful when I have slots in child components and would like to define them in the Enclosing Component. I don't know any solution for this.
sxzz commentedon Apr 3, 2023
Done in #7982