Skip to content

Commit

Permalink
feat: use __VLS_NormalizeEmits for template event type-check
Browse files Browse the repository at this point in the history
close #3379
  • Loading branch information
johnsoncodehk committed Sep 24, 2023
1 parent 8bbeaf0 commit 6df0db7
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 24 deletions.
7 changes: 6 additions & 1 deletion packages/vue-language-core/src/generators/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export function generate(
const scopedClasses: { className: string, offset: number; }[] = [];
const blockConditions: string[] = [];
const hasSlotElements = new Set<CompilerDOM.ElementNode>();
const componentCtxVar2EmitEventsVar = new Map<string, string>();

let hasSlot = false;
let elementIndex = 0;
Expand Down Expand Up @@ -785,7 +786,10 @@ export function generate(

if (tag !== 'template' && tag !== 'slot') {
componentCtxVar = `__VLS_${elementIndex++}`;
const componentEventsVar = `__VLS_${elementIndex++}`;
codes.push(`const ${componentCtxVar} = __VLS_pickFunctionalComponentCtx(${var_originalComponent}, ${var_componentInstance})!;\n`);
codes.push(`let ${componentEventsVar}!: __VLS_Prettify<__VLS_UnionToIntersection<__VLS_NormalizeEmits<typeof ${componentCtxVar}.emit>>>;\n`);
componentCtxVar2EmitEventsVar.set(componentCtxVar, componentEventsVar);
parentEl = node;
}

Expand Down Expand Up @@ -998,10 +1002,11 @@ export function generate(
&& prop.name === 'on'
&& prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION
) {
const eventsVar = componentCtxVar2EmitEventsVar.get(componentCtxVar);
const eventVar = `__VLS_${elementIndex++}`;
codes.push(
`let ${eventVar} = { '${prop.arg.loc.source}': `,
`__VLS_pickEvent(${componentCtxVar}.emit!, '${prop.arg.loc.source}' as const, ({} as __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>)`,
`__VLS_pickEvent(${eventsVar}['${prop.arg.loc.source}'], ({} as __VLS_FunctionalComponentProps<typeof ${componentVar}, typeof ${componentInstanceVar}>)`,
...createPropertyAccessCode([
camelize('on-' + prop.arg.loc.source), // onClickOutside
'template',
Expand Down
26 changes: 3 additions & 23 deletions packages/vue-language-core/src/utils/globalTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,26 +66,6 @@ type __VLS_WithComponent<N0 extends string, LocalComponents, N1 extends string,
type __VLS_FillingEventArg_ParametersLength<E extends (...args: any) => any> = __VLS_IsAny<Parameters<E>> extends true ? -1 : Parameters<E>['length'];
type __VLS_FillingEventArg<E> = E extends (...args: any) => any ? __VLS_FillingEventArg_ParametersLength<E> extends 0 ? ($event?: undefined) => ReturnType<E> : E : E;
type __VLS_EmitEvent<F, E> =
F extends {
(event: E, ...payload: infer P): any
} ? (...payload: P) => void
: F extends {
(event: E, ...payload: infer P): any
(...args: any): any
} ? (...payload: P) => void
: F extends {
(event: E, ...payload: infer P): any
(...args: any): any
(...args: any): any
} ? (...payload: P) => void
: F extends {
(event: E, ...payload: infer P): any
(...args: any): any
(...args: any): any
(...args: any): any
} ? (...payload: P) => void
: unknown | '[Type Warning] Volar could not infer $emit event more than 4 overloads without DefineComponent. see https://github.com/vuejs/language-tools/issues/60';
declare function __VLS_asFunctionalComponent<T, K = T extends new (...args: any) => any ? InstanceType<T> : unknown>(t: T, instance?: K):
T extends new (...args: any) => any
? (props: (K extends { $props: infer Props } ? Props : any)${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: {
Expand All @@ -98,10 +78,10 @@ declare function __VLS_asFunctionalComponent<T, K = T extends new (...args: any)
: (_: {}${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: {}${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'} } };
declare function __VLS_elementAsFunctionalComponent<T>(t: T): (_: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: any) => { __ctx?: { attrs?: any, expose?: any, slots?: any, emit?: any, props?: T${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'} } };
declare function __VLS_functionalComponentArgsRest<T extends (...args: any) => any>(t: T): Parameters<T>['length'] extends 2 ? [any] : [];
declare function __VLS_pickEvent<Emit, K, E>(emit: Emit, emitKey: K, event: E): __VLS_FillingEventArg<
declare function __VLS_pickEvent<E1, E2>(emitEvent: E1, propEvent: E2): __VLS_FillingEventArg<
__VLS_PickNotAny<
__VLS_AsFunctionOrAny<E>,
__VLS_AsFunctionOrAny<__VLS_EmitEvent<Emit, K>>
__VLS_AsFunctionOrAny<E2>,
__VLS_AsFunctionOrAny<E1>
>
> | undefined;
declare function __VLS_pickFunctionalComponentCtx<T, K>(comp: T, compInstance: K): __VLS_PickNotAny<
Expand Down

0 comments on commit 6df0db7

Please sign in to comment.