Skip to content

Commit c964b32

Browse files
authored
fix(component-meta): filter events out of props (#5547)
1 parent 539e53b commit c964b32

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

packages/component-meta/lib/base.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ interface ComponentMeta<T> {
240240
let _slots: ReturnType<typeof getSlots> | undefined;
241241
let _exposed: ReturnType<typeof getExposed> | undefined;
242242

243-
return {
243+
const meta = {
244244
get type() {
245245
return _type ?? (_type = getType());
246246
},
@@ -258,6 +258,8 @@ interface ComponentMeta<T> {
258258
},
259259
};
260260

261+
return meta;
262+
261263
function getType() {
262264
const $type = symbolProperties.find(prop => prop.escapedName === 'type');
263265

@@ -278,6 +280,10 @@ interface ComponentMeta<T> {
278280
const type = typeChecker.getTypeOfSymbolAtLocation($props, symbolNode);
279281
const properties = type.getProperties();
280282

283+
const eventProps = new Set(
284+
meta.events.map(event => `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}`),
285+
);
286+
281287
result = properties
282288
.map(prop => {
283289
const {
@@ -286,7 +292,7 @@ interface ComponentMeta<T> {
286292

287293
return resolveNestedProperties(prop);
288294
})
289-
.filter(prop => !vnodeEventRegex.test(prop.name));
295+
.filter(prop => !vnodeEventRegex.test(prop.name) && !eventProps.has(prop.name));
290296
}
291297

292298
// fill global

packages/component-meta/tests/index.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,21 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) =>
11681168
`);
11691169
});
11701170

1171+
test('component with both props and events', () => {
1172+
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/#5546/main.vue');
1173+
const meta = checker.getComponentMeta(componentPath);
1174+
1175+
expect(meta.type).toEqual(TypeMeta.Class);
1176+
1177+
// Nothing special about this prop
1178+
expect(meta.props.find(prop => prop.name === 'title')).toBeDefined();
1179+
// Event
1180+
expect(meta.props.find(prop => prop.name === 'onClose')).toBeUndefined();
1181+
expect(meta.events.find(event => event.name === 'close')).toBeDefined();
1182+
// Prop that starts with `on`
1183+
expect(meta.props.find(prop => prop.name === 'onCompleted')).toBeDefined();
1184+
});
1185+
11711186
test('non-component', () => {
11721187
const componentPath = path.resolve(
11731188
__dirname,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts" setup>
2+
defineProps<{
3+
title: string;
4+
onCompleted: () => void;
5+
}>()
6+
7+
defineEmits<{
8+
close: []
9+
}>()
10+
</script>
11+
12+
<template>
13+
<div></div>
14+
</template>

0 commit comments

Comments
 (0)