props on `template` are not checked
Vue - Official extension or vue-tsc version
2.0.26
VSCode version
1.92.0-insider
Vue version
3.4.31
TypeScript version
5.5.3
System Info
No response
Steps to reproduce
git clone [email protected]:brc-dd/volar-template-key-bug.gitpnpm ipnpm vue-tsc --noEmit
Pasting here for completeness:
<script setup lang="ts"></script>
<template>
<template v-if="true" :key=""></template>
<template v-if="true" :key="{}"></template>
<div v-if="true" :key=""></div>
<div v-if="true" :key="{}"></div>
</template>
What is expected?
Error on line 4, 5, 7, 8 of Foo.vue
What is actually happening?
Error is only on line 7, 8.
There should be an error on line 4 saying v-bind is missing expression.
There should be an error on line 5 saying Type '{}' is not assignable to type 'PropertyKey | undefined'.
Link to minimal reproduction
https://github.com/brc-dd/volar-template-key-bug
Any additional comments?
Is it possible to show vue errors when running vue-tsc? They are currently shown only in the editor. (Line 7 in the above example.)
Input
<script setup lang="ts"></script>
<template>
<template v-if="true" :key="">
<div></div>
</template>
<template v-if="true" :key="{}">
<div></div>
</template>
<div v-if="true" :key=""></div>
<div v-if="true" :key="{}"></div>
</template>
Output
// ...
if (true) {
__VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
}
if (true) {
__VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
}
if (true) {
__VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: ((__VLS_ctx.)), });
// @ts-ignore
[,];
}
if (true) {
__VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: (({})), });
}
// ...
Should?
// ...
if (true) {
- __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
+ __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: ((undefined))});
}
if (true) {
- __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
+ __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: (({}))});
}
if (true) {
- __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: ((__VLS_ctx.)), });
+ __VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: ((undefined))});
// @ts-ignore
[,];
}
if (true) {
__VLS_elementAsFunction(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({key: (({})), });
}
// ...
https://github.com/vuejs/core/blob/93324b2ec06b26662b77abc2a75d21ecbe8913db/packages/compiler-core/src/transforms/vIf.ts#L206-L216
A <template> with v-if will be turned into an IF_BRANCH node, we should handle it in https://github.com/vuejs/language-tools/blob/master/packages/language-core/lib/codegen/template/elementDirectives.ts.
Ah, it's not working for v-for in template's either. I had put v-if for easier repro. v-for + key is more common usage.
Should be fixed by https://github.com/vuejs/language-tools/commit/cb540323d4f0e80feed4feb4fea301f7d532f0c5? Do you mean there is no type checking?
Do you mean there is no type checking?
Yeah it's not there for key. This should've shown error in line 3:
<script setup lang="ts"></script>
<template>
<template v-for="x in [1]" :key="{}">
<div>{{ x }}</div>
</template>
</template>
Got it :open_hands:
My PR doesn't report v-bind is missing expression, since CompilerDOM.compile() itself doesn't throw on those invalid directives.
Ah yeah. It can be left I guess. I'll track it on the core repo. Looks like compiler-dom is generating invalid JS for <template v-for="x in [1]" :key="" /> without complaining.
Yeah, v-if with :key generates { key: 0 } while v-for with :key generates { key: }