diff --git a/CHANGELOG.md b/CHANGELOG.md index cb63a069d9..b2c028d754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### + +- 🙌 Fix v-bind modifiers causing TypeScript to not find type-checked template props correctly. Thanks to contribution from [@andrewisaburden](https://github.com/andrewisaburden). #2430. + ### 0.29.1 | 2020-11-08 | [VSIX](https://marketplace.visualstudio.com/_apis/public/gallery/publishers/octref/vsextensions/vetur/0.29.1/vspackage) - 🙌 Fix invalid `client/registerCapability` request. Thanks to contribution from [@rchl](https://github.com/rchl). #2388 and #2388. diff --git a/server/src/services/typescriptService/transformTemplate.ts b/server/src/services/typescriptService/transformTemplate.ts index 57f65e8bf5..ccb75c3890 100644 --- a/server/src/services/typescriptService/transformTemplate.ts +++ b/server/src/services/typescriptService/transformTemplate.ts @@ -251,7 +251,7 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa // Attribute name is specified // e.g. v-bind:value="foo" const fullName = - dir.key.modifiers.length === 0 + dir.key.modifiers.length === 0 || isVBind(dir) ? kebabCase(name.rawName) : [kebabCase(name.rawName), ...dir.key.modifiers.map(m => m.rawName)].join('.'); const propNameNode = ts.setSourceMapRange(ts.createStringLiteral(fullName), { @@ -327,7 +327,7 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa function element(el: AST.VElement, attrs: (AST.VAttribute | AST.VDirective)[]): ChildData { const vSlot = attrs.find(isVSlot); - if (vSlot) { + if (vSlot && isVDirective(vSlot)) { const index = attrs.indexOf(vSlot); const scope = el.variables.filter(v => v.kind === 'scope').map(v => v.id.name); @@ -342,7 +342,7 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa // v-for has higher priority than v-if // https://vuejs.org/v2/guide/list.html#v-for-with-v-if const vFor = attrs.find(isVFor); - if (vFor) { + if (vFor && isVDirective(vFor)) { const index = attrs.indexOf(vFor); const scope = el.variables.filter(v => v.kind === 'v-for').map(v => v.id.name); @@ -355,7 +355,7 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa } const vIf = attrs.find(isVIf); - if (vIf) { + if (vIf && isVDirective(vIf)) { const index = attrs.indexOf(vIf); return { type: 'v-if-family', @@ -380,7 +380,7 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa const attrs = el.startTag.attributes; const directive = attrs.find(isVElseIf) || attrs.find(isVElse); - if (!directive) { + if (!directive || !isVDirective(directive)) { return undefined; } @@ -743,43 +743,47 @@ export function getTemplateTransformFunctions(ts: T_TypeScript, childComponentNa return !node.directive; } - function isVModel(node: AST.VAttribute | AST.VDirective): node is AST.VAttribute { + function isVDirective(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + return node.directive; + } + + function isVModel(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'model'; } - function isVBind(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVBind(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'bind'; } - function isVBindShorthand(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVBindShorthand(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'bind' && node.key.name.rawName === ':'; } - function isVBindWithDynamicAttributeName(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVBindWithDynamicAttributeName(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.argument?.type === 'VExpressionContainer'; } - function isVOn(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVOn(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'on'; } - function isVIf(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVIf(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'if'; } - function isVElseIf(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVElseIf(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'else-if'; } - function isVElse(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVElse(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'else'; } - function isVFor(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVFor(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && node.key.name.name === 'for'; } - function isVSlot(node: AST.VAttribute | AST.VDirective): node is AST.VDirective { + function isVSlot(node: AST.VAttribute | AST.VDirective): boolean { return node.directive && (node.key.name.name === 'slot' || node.key.name.name === 'slot-scope'); } } diff --git a/test/interpolation/fixture/diagnostics/propTypeValidation/ParentRight.vue b/test/interpolation/fixture/diagnostics/propTypeValidation/ParentRight.vue index 8a32b809f5..e89512deb2 100644 --- a/test/interpolation/fixture/diagnostics/propTypeValidation/ParentRight.vue +++ b/test/interpolation/fixture/diagnostics/propTypeValidation/ParentRight.vue @@ -2,6 +2,7 @@
+