Skip to content

Commit f3479aa

Browse files
authored
fix(compiler-sfc): improved type resolution for function type aliases (#13452)
close #13444
1 parent 919c447 commit f3479aa

File tree

4 files changed

+40
-54
lines changed

4 files changed

+40
-54
lines changed

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -148,27 +148,6 @@ export default /*@__PURE__*/_defineComponent({
148148
149149
150150
151-
return { }
152-
}
153-
154-
})"
155-
`;
156-
157-
exports[`defineProps > w/ TSTypeAliasDeclaration 1`] = `
158-
"import { defineComponent as _defineComponent } from 'vue'
159-
type FunFoo<O> = (item: O) => boolean;
160-
type FunBar = FunFoo<number>;
161-
162-
export default /*@__PURE__*/_defineComponent({
163-
props: {
164-
foo: { type: Function, required: false, default: () => true },
165-
bar: { type: Function, required: false, default: () => true }
166-
},
167-
setup(__props: any, { expose: __expose }) {
168-
__expose();
169-
170-
171-
172151
return { }
173152
}
174153

packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -808,30 +808,4 @@ const props = defineProps({ foo: String })
808808
expect(content).toMatch(`foo: { default: 5.5, type: Number }`)
809809
assertCode(content)
810810
})
811-
812-
test('w/ TSTypeAliasDeclaration', () => {
813-
const { content } = compile(`
814-
<script setup lang="ts">
815-
type FunFoo<O> = (item: O) => boolean;
816-
type FunBar = FunFoo<number>;
817-
withDefaults(
818-
defineProps<{
819-
foo?: FunFoo<number>;
820-
bar?: FunBar;
821-
}>(),
822-
{
823-
foo: () => true,
824-
bar: () => true,
825-
},
826-
);
827-
</script>
828-
`)
829-
assertCode(content)
830-
expect(content).toMatch(
831-
`foo: { type: Function, required: false, default: () => true }`,
832-
)
833-
expect(content).toMatch(
834-
`bar: { type: Function, required: false, default: () => true }`,
835-
)
836-
})
837811
})

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,38 @@ describe('resolveType', () => {
731731
})
732732
})
733733

734+
describe('type alias declaration', () => {
735+
// #13240
736+
test('function type', () => {
737+
expect(
738+
resolve(`
739+
type FunFoo<O> = (item: O) => boolean;
740+
type FunBar = FunFoo<number>;
741+
defineProps<{
742+
foo?: FunFoo<number>;
743+
bar?: FunBar;
744+
}>()
745+
`).props,
746+
).toStrictEqual({
747+
foo: ['Function'],
748+
bar: ['Function'],
749+
})
750+
})
751+
752+
test('fallback to Unknown', () => {
753+
expect(
754+
resolve(`
755+
type Brand<T> = T & {};
756+
defineProps<{
757+
foo: Brand<string>;
758+
}>()
759+
`).props,
760+
).toStrictEqual({
761+
foo: [UNKNOWN_TYPE],
762+
})
763+
})
764+
})
765+
734766
describe('generics', () => {
735767
test('generic with type literal', () => {
736768
expect(

packages/compiler-sfc/src/script/resolveType.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,13 +1588,14 @@ export function inferRuntimeType(
15881588
case 'TSTypeReference': {
15891589
const resolved = resolveTypeReference(ctx, node, scope)
15901590
if (resolved) {
1591-
if (resolved.type === 'TSTypeAliasDeclaration') {
1592-
return inferRuntimeType(
1593-
ctx,
1594-
resolved.typeAnnotation,
1595-
resolved._ownerScope,
1596-
isKeyOf,
1597-
)
1591+
// #13240
1592+
// Special case for function type aliases to ensure correct runtime behavior
1593+
// other type aliases still fallback to unknown as before
1594+
if (
1595+
resolved.type === 'TSTypeAliasDeclaration' &&
1596+
resolved.typeAnnotation.type === 'TSFunctionType'
1597+
) {
1598+
return ['Function']
15981599
}
15991600
return inferRuntimeType(ctx, resolved, resolved._ownerScope, isKeyOf)
16001601
}

0 commit comments

Comments
 (0)