]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): handle imported types from default exports
authorEvan You <yyx990803@gmail.com>
Thu, 18 May 2023 08:15:27 +0000 (16:15 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 18 May 2023 08:15:27 +0000 (16:15 +0800)
close #8355

packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
packages/compiler-sfc/src/script/resolveType.ts

index dd47344277c562b19b68dcaf877f0d4097441682..f671541977b3e1eea6974037e14cae4b7b72d8b5 100644 (file)
@@ -574,6 +574,47 @@ describe('resolveType', () => {
       expect(deps && [...deps]).toStrictEqual(Object.keys(files))
     })
 
+    test('relative (default export)', () => {
+      const files = {
+        '/foo.ts': `export default interface P { foo: string }`,
+        '/bar.ts': `type X = { bar: string }; export default X`
+      }
+      const { props, deps } = resolve(
+        `
+        import P from './foo'
+        import X from './bar'
+        defineProps<P & X>()
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
+        foo: ['String'],
+        bar: ['String']
+      })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+    })
+
+    test('relative (default re-export)', () => {
+      const files = {
+        '/bar.ts': `export { default } from './foo'`,
+        '/foo.ts': `export default interface P { foo: string }; export interface PP { bar: number }`,
+        '/baz.ts': `export { PP as default } from './foo'`
+      }
+      const { props, deps } = resolve(
+        `
+        import P from './bar'
+        import PP from './baz'
+        defineProps<P & PP>()
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
+        foo: ['String'],
+        bar: ['Number']
+      })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
+    })
+
     test('relative (dynamic import)', () => {
       const files = {
         '/foo.ts': `export type P = { foo: string, bar: import('./bar').N }`,
index 775aa41ff83101ab86552ee55780390b6af8a02c..f4e1915255e7fc50d61c9c7e1db5f33a5bd860aa 100644 (file)
@@ -1144,6 +1144,18 @@ function recordTypes(
           stmt.source.value
         )
         Object.assign(scope.exportedTypes, sourceScope.exportedTypes)
+      } else if (stmt.type === 'ExportDefaultDeclaration' && stmt.declaration) {
+        if (stmt.declaration.type !== 'Identifier') {
+          recordType(stmt.declaration, types, declares, 'default')
+          recordType(
+            stmt.declaration,
+            exportedTypes,
+            exportedDeclares,
+            'default'
+          )
+        } else if (types[stmt.declaration.name]) {
+          exportedTypes['default'] = types[stmt.declaration.name]
+        }
       }
     }
   }
@@ -1160,13 +1172,14 @@ function recordTypes(
 function recordType(
   node: Node,
   types: Record<string, Node>,
-  declares: Record<string, Node>
+  declares: Record<string, Node>,
+  overwriteId?: string
 ) {
   switch (node.type) {
     case 'TSInterfaceDeclaration':
     case 'TSEnumDeclaration':
     case 'TSModuleDeclaration': {
-      const id = getId(node.id)
+      const id = overwriteId || getId(node.id)
       let existing = types[id]
       if (existing) {
         if (node.type === 'TSModuleDeclaration') {
@@ -1199,7 +1212,7 @@ function recordType(
       break
     }
     case 'ClassDeclaration':
-      types[getId(node.id)] = node
+      types[overwriteId || getId(node.id)] = node
       break
     case 'TSTypeAliasDeclaration':
       types[node.id.name] = node.typeAnnotation