Skip to content

Commit

Permalink
fix: cannot use generic components inside defineComponent
Browse files Browse the repository at this point in the history
close #2709
  • Loading branch information
johnsoncodehk committed Apr 25, 2023
1 parent 987b2f3 commit 3c564b0
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 10 deletions.
4 changes: 2 additions & 2 deletions packages/vue-language-core/src/generators/script.ts
Expand Up @@ -295,7 +295,7 @@ export function generate(
codes.push(`>`);
codes.push('(\n');
codes.push(`__VLS_props: typeof __VLS_setup['props'] & import('vue').VNodeProps,\n`);
codes.push(`__VLS_ctx?: Pick<typeof __VLS_setup, 'expose' | 'attrs' | 'emit' | 'slots'>,\n`);
codes.push(`__VLS_ctx?: Pick<typeof __VLS_setup, 'attrs' | 'emit' | 'slots'>,\n`);
codes.push('__VLS_setup = (() => {\n');
scriptSetupGeneratedOffset = generateSetupFunction(true, 'none', definePropMirrors);

Expand Down Expand Up @@ -411,7 +411,7 @@ export function generate(
codes.push('emit: typeof __VLS_emit');
codes.push('};\n');
codes.push('})(),\n');
codes.push(') => ({} as import("vue").VNode & { __props?: typeof __VLS_props, __ctx?: typeof __VLS_ctx }))');
codes.push(') => ({} as import("vue").VNode & { __ctx?: typeof __VLS_setup }))');
}
else if (!sfc.script) {
// no script block, generate script setup code at root
Expand Down
7 changes: 3 additions & 4 deletions packages/vue-language-core/src/utils/localTypes.ts
Expand Up @@ -91,13 +91,12 @@ export declare function asFunctionalComponent<T, K = T extends new (...args: any
T extends new (...args: any) => any
? (props: (K extends { $props: infer Props } ? Props : any)${vueCompilerOptions.strictTemplates ? '' : ' & Record<string, unknown>'}, ctx?: {
attrs?: any,
expose?(exposed: K): void,
slots?: K extends { ${getSlotsPropertyName(vueCompilerOptions.target)}: infer Slots } ? Slots : any,
emit?: K extends { $emit: infer Emit } ? Emit : any
}) => JSX.Element & { __ctx?: typeof ctx, __props?: typeof props }
}) => JSX.Element & { __ctx?: typeof ctx & { props?: typeof props; expose?(exposed: K): void; } }
: T extends () => any ? (props: {}, ctx?: any) => ReturnType<T>
: T extends (...args: any) => any ? T
: (_: T & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: unknown, expose?: unknown, slots?: unknown, emit?: unknown }, __props?: T & Record<string, unknown> }; // IntrinsicElement
: (_: T & Record<string, unknown>, ctx?: any) => { __ctx?: { attrs?: unknown, expose?: unknown, slots?: unknown, emit?: unknown, props?: T & Record<string, unknown> } }; // IntrinsicElement
declare function functionalComponentArgsRest<T extends (...args: any) => any>(t: T): Parameters<T>['length'] extends 2 ? [any] : [];
export declare function pickEvent<Emit, K, E>(emit: Emit, emitKey: K, event: E): FillingEventArg<
PickNotAny<
Expand All @@ -112,7 +111,7 @@ export declare function pickFunctionalComponentCtx<T, K>(comp: T, compInstance:
type AsFunctionOrAny<F> = unknown extends F ? any : ((...args: any) => any) extends F ? F : any;
export declare function componentProps<T, K>(comp: T, fnReturn: K):
PickNotAny<K, {}> extends { __props: infer P } ? NonNullable<P>
PickNotAny<K, {}> extends { __ctx: { props: infer P } } ? NonNullable<P>
: T extends (props: infer P, ...args: any) => any ? NonNullable<P> :
{};
`.trim();
Expand Down
10 changes: 10 additions & 0 deletions packages/vue-test-workspace/vue-tsc/#2709/App.vue
@@ -0,0 +1,10 @@
<script lang="ts">
import { defineComponent } from 'vue';
import MyList from './MyList.vue';
export default defineComponent({
components: {
MyList, // <-- error: No overload matches this call
},
});
</script>
9 changes: 9 additions & 0 deletions packages/vue-test-workspace/vue-tsc/#2709/MyList.vue
@@ -0,0 +1,9 @@
<script setup lang="ts" generic="T extends string | number">
defineProps<{ options: T[] }>();
</script>

<template>
<ul>
<li v-for="option of options">{{ option }}</li>
</ul>
</template>
4 changes: 2 additions & 2 deletions packages/vue-test-workspace/vue-tsc/components/main.vue
Expand Up @@ -65,15 +65,15 @@ const ScriptSetupDefaultPropsExact = defineComponent({
// vue 3.3 generic
declare const ScriptSetupGenericExact: <T, >(
_props: import('vue').VNodeProps & NonNullable<typeof _setup>['props'],
_ctx?: Pick<NonNullable<typeof _setup>, 'expose' | 'attrs' | 'emit' | 'slots'>,
_ctx?: Pick<NonNullable<typeof _setup>, 'attrs' | 'emit' | 'slots'>,
_setup?: {
props: { foo: T } & { [K in keyof JSX.ElementChildrenAttribute]?: { default(data: T): any } },
attrs: any,
slots: { default(data: T): any },
emit: { (e: 'bar', data: T): void },
expose(_exposed: { baz: T }): void,
}
) => import('vue').VNode & { __props?: typeof _props, __ctx?: typeof _ctx };
) => import('vue').VNode & { __ctx?: typeof _setup };
exactType(ScriptSetup, ScriptSetupExact);
exactType(ScriptSetupExpose, ScriptSetupExposeExact);
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-test-workspace/vue-tsc/defineProp_B/main.vue
Expand Up @@ -20,7 +20,7 @@ const ScriptSetupExact = defineComponent({
});
declare const ScriptSetupGenericExact: <T, >(
_props: import('vue').VNodeProps & NonNullable<typeof _setup>['props'],
_ctx?: Pick<NonNullable<typeof _setup>, 'expose' | 'attrs' | 'emit' | 'slots'>,
_ctx?: Pick<NonNullable<typeof _setup>, 'attrs' | 'emit' | 'slots'>,
_setup?: {
props: {
a?: T | undefined;
Expand All @@ -33,7 +33,7 @@ declare const ScriptSetupGenericExact: <T, >(
emit: any,
expose(_exposed: {}): void,
}
) => import('vue').VNode & { __props?: typeof _props, __ctx?: typeof _ctx };
) => import('vue').VNode & { __ctx?: typeof _setup };
exactType(ScriptSetup, ScriptSetupExact);
exactType(ScriptSetupGeneric, ScriptSetupGenericExact);
Expand Down

0 comments on commit 3c564b0

Please sign in to comment.