]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): improved type resolution for function type aliases (#13452)
authorTycho <jh.leong@outlook.com>
Wed, 18 Jun 2025 12:54:09 +0000 (20:54 +0800)
committerGitHub <noreply@github.com>
Wed, 18 Jun 2025 12:54:09 +0000 (20:54 +0800)
close #13444

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

index 11367463cd963182542df5491235ae7c6520408e..fce04c851122f46104e8891b676335896f277233 100644 (file)
@@ -148,27 +148,6 @@ export default /*@__PURE__*/_defineComponent({
 
       
     
-return {  }
-}
-
-})"
-`;
-
-exports[`defineProps > w/ TSTypeAliasDeclaration 1`] = `
-"import { defineComponent as _defineComponent } from 'vue'
-type FunFoo<O> = (item: O) => boolean;
-    type FunBar = FunFoo<number>;
-    
-export default /*@__PURE__*/_defineComponent({
-  props: {
-    foo: { type: Function, required: false, default: () => true },
-    bar: { type: Function, required: false, default: () => true }
-  },
-  setup(__props: any, { expose: __expose }) {
-  __expose();
-
-    
-    
 return {  }
 }
 
index dcf6341a9fc61bdad093fe85b0d852484fbaa0ea..836badb51c8ae568fda4db425a01d093a124c455 100644 (file)
@@ -808,30 +808,4 @@ const props = defineProps({ foo: String })
     expect(content).toMatch(`foo: { default: 5.5, type: Number }`)
     assertCode(content)
   })
-
-  test('w/ TSTypeAliasDeclaration', () => {
-    const { content } = compile(`
-    <script setup lang="ts">
-    type FunFoo<O> = (item: O) => boolean;
-    type FunBar = FunFoo<number>;
-    withDefaults(
-      defineProps<{
-        foo?: FunFoo<number>;
-        bar?: FunBar;
-      }>(),
-      {
-        foo: () => true,
-        bar: () => true,
-      },
-    );
-    </script>
-      `)
-    assertCode(content)
-    expect(content).toMatch(
-      `foo: { type: Function, required: false, default: () => true }`,
-    )
-    expect(content).toMatch(
-      `bar: { type: Function, required: false, default: () => true }`,
-    )
-  })
 })
index 68fc5cc3159731e2cbd2b84b9c16a356bd6b6374..c6a2f9c38dd315ad9d413157ad793ebe0b89c249 100644 (file)
@@ -731,6 +731,38 @@ describe('resolveType', () => {
     })
   })
 
+  describe('type alias declaration', () => {
+    // #13240
+    test('function type', () => {
+      expect(
+        resolve(`
+      type FunFoo<O> = (item: O) => boolean;
+      type FunBar = FunFoo<number>;
+      defineProps<{
+        foo?: FunFoo<number>;
+        bar?: FunBar;
+      }>()
+      `).props,
+      ).toStrictEqual({
+        foo: ['Function'],
+        bar: ['Function'],
+      })
+    })
+
+    test('fallback to Unknown', () => {
+      expect(
+        resolve(`
+      type Brand<T> = T & {};
+      defineProps<{
+        foo: Brand<string>;
+      }>()
+      `).props,
+      ).toStrictEqual({
+        foo: [UNKNOWN_TYPE],
+      })
+    })
+  })
+
   describe('generics', () => {
     test('generic with type literal', () => {
       expect(
index 85832dfc39a02128c28a081fbfd80729a159e9b9..910e8839a3ebee3e5ea6d7335909f33e7db27b6c 100644 (file)
@@ -1588,13 +1588,14 @@ export function inferRuntimeType(
       case 'TSTypeReference': {
         const resolved = resolveTypeReference(ctx, node, scope)
         if (resolved) {
-          if (resolved.type === 'TSTypeAliasDeclaration') {
-            return inferRuntimeType(
-              ctx,
-              resolved.typeAnnotation,
-              resolved._ownerScope,
-              isKeyOf,
-            )
+          // #13240
+          // Special case for function type aliases to ensure correct runtime behavior
+          // other type aliases still fallback to unknown as before
+          if (
+            resolved.type === 'TSTypeAliasDeclaration' &&
+            resolved.typeAnnotation.type === 'TSFunctionType'
+          ) {
+            return ['Function']
           }
           return inferRuntimeType(ctx, resolved, resolved._ownerScope, isKeyOf)
         }