Kaynağa Gözat

fix(compiler-vapor): handle TSNonNullExpression and improve expression processing (#14097)

edison 5 ay önce
ebeveyn
işleme
092c73ae28

+ 14 - 0
packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap

@@ -1,5 +1,19 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
+exports[`cache multiple access > TSNonNullExpression 1`] = `
+"import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("<div></div>", true)
+
+export function render(_ctx) {
+  const n0 = t0()
+  _renderEffect(() => {
+    const _obj = _ctx.obj
+    _setProp(n0, "id", _obj.foo + _obj.bar)
+  })
+  return n0
+}"
+`;
+
 exports[`cache multiple access > cache variable used in both property shorthand and normal binding 1`] = `
 "import { setStyle as _setStyle, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
 const t0 = _template("<div></div>", true)

+ 7 - 0
packages/compiler-vapor/__tests__/transforms/vBind.spec.ts

@@ -836,6 +836,13 @@ describe('cache multiple access', () => {
     expect(code).contains('_setProp(n0, "id", _obj?.foo + _obj?.bar)')
   })
 
+  test('TSNonNullExpression', () => {
+    const { code } = compileWithVBind(`<div :id="obj!.foo + obj!.bar"></div>`)
+    expect(code).matchSnapshot()
+    expect(code).contains('const _obj = _ctx.obj')
+    expect(code).contains('_setProp(n0, "id", _obj.foo + _obj.bar)')
+  })
+
   test('not cache variable only used in property shorthand', () => {
     const { code } = compileWithVBind(`
         <div :style="{color}" />

+ 9 - 2
packages/compiler-vapor/src/generators/expression.ts

@@ -513,7 +513,10 @@ function processRepeatedExpressions(
   const declarations: DeclarationValue[] = []
   const seenExp = expressions.reduce(
     (acc, exp) => {
-      const variables = expToVariableMap.get(exp)!.map(v => v.name)
+      const vars = expToVariableMap.get(exp)
+      if (!vars) return acc
+
+      const variables = vars.map(v => v.name)
       // only handle expressions that are not identifiers
       if (
         exp.ast &&
@@ -673,6 +676,8 @@ function extractMemberExpression(
         ? `[${extractMemberExpression(exp.property, onIdentifier)}]`
         : `.${extractMemberExpression(exp.property, NOOP)}`
       return `${object}${prop}`
+    case 'TSNonNullExpression': // foo!.bar
+      return `${extractMemberExpression(exp.expression, onIdentifier)}!`
     default:
       return ''
   }
@@ -680,6 +685,8 @@ function extractMemberExpression(
 
 const isMemberExpression = (node: Node) => {
   return (
-    node.type === 'MemberExpression' || node.type === 'OptionalMemberExpression'
+    node.type === 'MemberExpression' ||
+    node.type === 'OptionalMemberExpression' ||
+    node.type === 'TSNonNullExpression'
   )
 }