From f3479aac9625f4459e650d1c0a70e73863147903 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 18 Jun 2025 20:54:09 +0800 Subject: [PATCH] fix(compiler-sfc): improved type resolution for function type aliases (#13452) close #13444 --- .../__snapshots__/defineProps.spec.ts.snap | 21 ------------ .../compileScript/defineProps.spec.ts | 26 --------------- .../compileScript/resolveType.spec.ts | 32 +++++++++++++++++++ .../compiler-sfc/src/script/resolveType.ts | 15 +++++---- 4 files changed, 40 insertions(+), 54 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap index 11367463c..fce04c851 100644 --- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap @@ -148,27 +148,6 @@ export default /*@__PURE__*/_defineComponent({ -return { } -} - -})" -`; - -exports[`defineProps > w/ TSTypeAliasDeclaration 1`] = ` -"import { defineComponent as _defineComponent } from 'vue' -type FunFoo = (item: O) => boolean; - type FunBar = FunFoo; - -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 { } } diff --git a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts index dcf6341a9..836badb51 100644 --- a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts @@ -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(` - - `) - assertCode(content) - expect(content).toMatch( - `foo: { type: Function, required: false, default: () => true }`, - ) - expect(content).toMatch( - `bar: { type: Function, required: false, default: () => true }`, - ) - }) }) diff --git a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts index 68fc5cc31..c6a2f9c38 100644 --- a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts @@ -731,6 +731,38 @@ describe('resolveType', () => { }) }) + describe('type alias declaration', () => { + // #13240 + test('function type', () => { + expect( + resolve(` + type FunFoo = (item: O) => boolean; + type FunBar = FunFoo; + defineProps<{ + foo?: FunFoo; + bar?: FunBar; + }>() + `).props, + ).toStrictEqual({ + foo: ['Function'], + bar: ['Function'], + }) + }) + + test('fallback to Unknown', () => { + expect( + resolve(` + type Brand = T & {}; + defineProps<{ + foo: Brand; + }>() + `).props, + ).toStrictEqual({ + foo: [UNKNOWN_TYPE], + }) + }) + }) + describe('generics', () => { test('generic with type literal', () => { expect( diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts index 85832dfc3..910e8839a 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -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) }