Skip to content

Commit

Permalink
feat(language-core): use internal options for directly exposing user …
Browse files Browse the repository at this point in the history
…emit types

close #3893
  • Loading branch information
johnsoncodehk committed Apr 27, 2024
1 parent 68edc1d commit a27caa1
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 7 deletions.
1 change: 1 addition & 0 deletions packages/component-meta/lib/base.ts
Expand Up @@ -565,6 +565,7 @@ function createSchemaResolvers(

return {
name: (typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode) as ts.StringLiteralType).value,
description: ts.displayPartsToString(call.getDocumentationComment(typeChecker)),
type: typeChecker.typeToString(subtype),
rawType: rawType ? subtype : undefined,
signature: typeChecker.signatureToString(call),
Expand Down
1 change: 1 addition & 0 deletions packages/component-meta/lib/types.ts
Expand Up @@ -36,6 +36,7 @@ export interface PropertyMeta {

export interface EventMeta {
name: string;
description: string;
type: string;
rawType?: ts.Type;
signature: string;
Expand Down
25 changes: 21 additions & 4 deletions packages/component-meta/tests/index.spec.ts
Expand Up @@ -26,14 +26,14 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ
// expect(meta.type).toEqual(TypeMeta.Class);

const foo = meta.props.find(prop => prop.name === 'foo');
const onUpdateFoo = meta.events.find(event => event.name === 'update:foo')
const onUpdateFoo = meta.events.find(event => event.name === 'update:foo');

const bar = meta.props.find(prop => prop.name === 'bar');
const onUpdateBar = meta.events.find(event => event.name === 'update:bar')
const onUpdateBar = meta.events.find(event => event.name === 'update:bar');

const qux = meta.props.find(prop => prop.name === 'qux');
const quxModifiers = meta.props.find(prop => prop.name === 'quxModifiers');
const onUpdateQux = meta.events.find(event => event.name === 'update:qux')
const onUpdateQux = meta.events.find(event => event.name === 'update:qux');

expect(foo).toBeDefined();
expect(bar).toBeDefined();
Expand All @@ -42,7 +42,7 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ
expect(onUpdateFoo).toBeDefined();
expect(onUpdateBar).toBeDefined();
expect(onUpdateQux).toBeDefined();
})
});

test('reference-type-props', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/reference-type-props/component.vue');
Expand Down Expand Up @@ -724,6 +724,23 @@ const worker = (checker: ComponentMetaChecker, withTsconfig: boolean) => describ
expect(b).toBeDefined();
});

test('emits-generic', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/events/component-generic.vue');
const meta = checker.getComponentMeta(componentPath);
const foo = meta.events.find(event =>event.name === 'foo');

expect(foo?.description).toBe('Emitted when foo...');
});

// Wait for https://github.com/vuejs/core/pull/10801
test.skip('emits-class', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/events/component-class.vue');
const meta = checker.getComponentMeta(componentPath);
const foo = meta.events.find(event =>event.name === 'foo');

expect(foo?.description).toBe('Emitted when foo...');
});

test('ts-named-exports', () => {
const componentPath = path.resolve(__dirname, '../../../test-workspace/component-meta/ts-named-export/component.ts');
const exportNames = checker.getExportNames(componentPath);
Expand Down
3 changes: 3 additions & 0 deletions packages/language-core/lib/codegen/script/component.ts
Expand Up @@ -117,4 +117,7 @@ export function* generateScriptSetupOptions(
if (scriptSetupRanges.props.define?.typeArg) {
yield `__typeProps: typeof __VLS_typeProps,${newLine}`;
}
if (scriptSetupRanges.emits.define) {
yield `__typeEmits: typeof ${scriptSetupRanges.emits.name ?? '__VLS_emit'},${newLine}`;
}
}
51 changes: 48 additions & 3 deletions packages/tsc/tests/__snapshots__/dts.spec.ts.snap
Expand Up @@ -28,6 +28,51 @@ export default _default;
"
`;

exports[`vue-tsc-dts > Input: events/component-class.vue, Output: events/component-class.vue.d.ts 1`] = `
"declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
foo: (value: string) => void;
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>> & {
onFoo?: (value: string) => any;
}, {}, {}>;
export default _default;
"
`;

exports[`vue-tsc-dts > Input: events/component-generic.vue, Output: events/component-generic.vue.d.ts 1`] = `
"declare const _default: <T>(__VLS_props: {
onFoo?: (value: string) => any;
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: {
slots: {};
attrs: any;
emit: (evt: "foo", value: string) => void;
}, __VLS_expose?: (exposed: import('vue').ShallowUnwrapRef<{}>) => void, __VLS_setup?: Promise<{
props: {
onFoo?: (value: string) => any;
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
attrs: any;
slots: {};
emit: (evt: "foo", value: string) => void;
}>) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
[key: string]: any;
}> & {
__ctx?: {
props: {
onFoo?: (value: string) => any;
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
attrs: any;
slots: {};
emit: (evt: "foo", value: string) => void;
};
};
export default _default;
type __VLS_Prettify<T> = {
[K in keyof T]: T[K];
} & {};
"
`;
exports[`vue-tsc-dts > Input: generic/component.vue, Output: generic/component.vue.d.ts 1`] = `
"declare const _default: <T>(__VLS_props: {
onBar?: (data: number) => any;
Expand Down Expand Up @@ -268,13 +313,13 @@ exports[`vue-tsc-dts > Input: reference-type-events/component.vue, Output: refer
}) => void;
baz: () => void;
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>> & {
onFoo?: (data?: {
foo: string;
}) => any;
onBar?: (value: {
arg1: number;
arg2?: any;
}) => any;
onFoo?: (data?: {
foo: string;
}) => any;
onBaz?: () => any;
}, {}, {}>;
export default _default;
Expand Down
6 changes: 6 additions & 0 deletions test-workspace/component-meta/events/component-class.vue
@@ -0,0 +1,6 @@
<script setup lang="ts">
const emit = defineEmits<{
/** Emitted when foo... */
(evt: "foo", value: string): void
}>();
</script>
6 changes: 6 additions & 0 deletions test-workspace/component-meta/events/component-generic.vue
@@ -0,0 +1,6 @@
<script setup lang="ts" generic="T">
const emit = defineEmits<{
/** Emitted when foo... */
(evt: "foo", value: string): void
}>();
</script>

0 comments on commit a27caa1

Please sign in to comment.