Преглед на файлове

fix(compiler-sfc): always generate runtime prop type for Function (#7112)

fix #7111
三咲智子 Kevin Deng преди 3 години
родител
ревизия
584eae60d1

+ 29 - 0
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

@@ -1729,6 +1729,35 @@ const props = __props as {
 
       
       
+return { props, get defaults() { return defaults } }
+}
+
+})"
+`;
+
+exports[`SFC compile <script setup> with TypeScript withDefaults (dynamic) w/ production mode 1`] = `
+"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
+import { defaults } from './foo'
+      
+export default /*#__PURE__*/_defineComponent({
+  props: _mergeDefaults({
+    foo: { type: Function },
+    bar: { type: Boolean },
+    baz: { type: [Boolean, Function] },
+    qux: null
+  }, { ...defaults }),
+  setup(__props: any, { expose }) {
+  expose();
+
+const props = __props as {
+        foo: () => void
+        bar: boolean
+        baz: boolean | (() => void)
+        qux: string | number
+      };
+
+      
+      
 return { props, get defaults() { return defaults } }
 }
 

+ 29 - 0
packages/compiler-sfc/__tests__/compileScript.spec.ts

@@ -1144,6 +1144,35 @@ const emit = defineEmits(['a', 'b'])
       )
     })
 
+    // #7111
+    test('withDefaults (dynamic) w/ production mode', () => {
+      const { content } = compile(
+        `
+      <script setup lang="ts">
+      import { defaults } from './foo'
+      const props = withDefaults(defineProps<{
+        foo: () => void
+        bar: boolean
+        baz: boolean | (() => void)
+        qux: string | number
+      }>(), { ...defaults })
+      </script>
+      `,
+        { isProd: true }
+      )
+      assertCode(content)
+      expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+      expect(content).toMatch(
+        `
+  _mergeDefaults({
+    foo: { type: Function },
+    bar: { type: Boolean },
+    baz: { type: [Boolean, Function] },
+    qux: null
+  }, { ...defaults })`.trim()
+      )
+    })
+
     test('defineEmits w/ type', () => {
       const { content } = compile(`
       <script setup lang="ts">

+ 3 - 6
packages/compiler-sfc/src/compileScript.ts

@@ -822,12 +822,9 @@ export function compileScript(
           )}, required: ${required}${
             defaultString ? `, ${defaultString}` : ``
           } }`
-        } else if (
-          type.some(
-            el => el === 'Boolean' || (defaultString && el === 'Function')
-          )
-        ) {
-          // #4783 production: if boolean or defaultString and function exists, should keep the type.
+        } else if (type.some(el => el === 'Boolean' || el === 'Function')) {
+          // #4783, #7111 for boolean or function, should keep the type
+          // in production
           return `${key}: { type: ${toRuntimeTypeString(type)}${
             defaultString ? `, ${defaultString}` : ``
           } }`