Interface hoisting for defineProps #2421
skirtles-code
started this conversation in
General
Replies: 1 comment 1 reply
-
Fixed by #2582 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Overview
Type-based props support the use of a local
interface
, such as:Or:
However, both of these usages can lead to an error:
This doesn't happen for all projects, it depends on the TS settings. For example, the following seems to trigger the error:
create-vue
sometimes includes this setting, depending on the set of options chosen when creating the project. For example, choosing TypeScript and Vitest leads to this setting being included.Using
"declaration": true
instead of"composite": true
will also trigger the error.This error can also be seen using
vue-tsc
with--emitDeclarationOnly
.Why Does This Happen?
The props are part of the exported type of the component. The
interface
passed todefineProps
is treated as though it is inside thesetup
function. It needs hoisting in the virtual code to avoid the error:Currently, the only way to trigger hoisting in Volar is to use
export
. This can be used as a workaround to resolve this error, but it isn't particularly intuitive that this should be required. Theexport default
is being handled implicitly, so why not the things it depends on?The problem only occurs for
interface
, nottype
. I'm not clear why that is, or what ramifications it has for the proposal to hoist interfaces.How Would Hoisting Work?
Things used by
defineProps<X>()
would be hoisted, recursively hoisting anything that it depends on:Thanks to LinusBorg for coming up with this example:
A note from Evan when discussing this:
The SFC compiler maybe has an easier task here than Volar. The compiler only needs enough information to generate the runtime
props
option, whereas Volar andvue-tsc
need to be able to construct actual TS types that can be consumed externally, e.g. in other projects.In cases where the props depend on something that can't be hoisted, my suggestion would be to provide a clearer error message explaining the problem.
Another edge case to consider is the potential for naming collisions. Things defined in a separate
<script>
block could have the same names as the things being hoisted.Implications of 3.3
With the proposal for 3.3 to support importing types, I suspect we're going to get much wider use of interfaces for props:
References
We've had this problem reported multiple times against the docs repo. For example:
The underlying complaint is that the code shown in the docs leads to an error in Volar. Understandably this makes people think the docs are wrong.
This has also been reported in this repo:
I think that issue should be reopened. It may not be considered a bug, but there is an unresolved DX issue here.
Beta Was this translation helpful? Give feedback.
All reactions