From 6201b8496e63129ffef0cf9e8156102f2144f2f9 Mon Sep 17 00:00:00 2001
From: KazariEX <1364035137@qq.com>
Date: Tue, 21 Jan 2025 23:33:04 +0800
Subject: [PATCH] feat: support native element

---
 .../language-core/lib/codegen/globalTypes.ts  | 27 ++++++++++---------
 .../lib/codegen/template/element.ts           |  6 +++++
 .../vue3/slot-children/main.vue               |  4 +++
 .../vue3/slot-children/parent.vue             |  2 +-
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts
index d6942dc474..d5b56dda88 100644
--- a/packages/language-core/lib/codegen/globalTypes.ts
+++ b/packages/language-core/lib/codegen/globalTypes.ts
@@ -57,6 +57,20 @@ export function generateGlobalTypes(lib: string, target: number, strictTemplates
 		? K extends { __ctx?: { props?: infer P } } ? NonNullable<P> : never
 		: T extends (props: infer P, ...args: any) => any ? P
 		: {};
+	type __VLS_FunctionalGeneralComponent<T> = (props: ${fnPropsType}, ctx?: any) => __VLS_Element & {
+		__ctx?: {
+			attrs?: any,
+			slots?: T extends { ${getSlotsPropertyName(target)}: infer Slots } ? Slots : any,
+			emit?: T extends { $emit: infer Emit } ? Emit : any,
+			props?: ${fnPropsType},
+			expose?(exposed: T): void,
+		}
+	};
+	type __VLS_NormalizeSlotReturns<S, R = ReturnType<NonNullable<S>>> = R extends any[] ? {
+		[K in keyof R]: R[K] extends { __ctx?: any } | Element
+			? R[K]
+			: ReturnType<__VLS_FunctionalGeneralComponent<R[K]>>
+	} : R;
 	type __VLS_IsFunction<T, K> = K extends keyof T
 		? __VLS_IsAny<T[K]> extends false
 		? unknown extends T[K]
@@ -99,19 +113,6 @@ export function generateGlobalTypes(lib: string, target: number, strictTemplates
 	type __VLS_PrettifyGlobal<T> = { [K in keyof T]: T[K]; } & {};
 	type __VLS_UseTemplateRef<T> = Readonly<import('${lib}').ShallowRef<T | null>>;
 
-	type __VLS_FunctionalGeneralComponent<T> = (props: ${fnPropsType}, ctx?: any) => __VLS_Element & {
-		__ctx?: {
-			attrs?: any,
-			slots?: T extends { ${getSlotsPropertyName(target)}: infer Slots } ? Slots : any,
-			emit?: T extends { $emit: infer Emit } ? Emit : any,
-			props?: ${fnPropsType},
-			expose?(exposed: T): void,
-		}
-	};
-	type __VLS_NormalizeSlotReturns<S, R = ReturnType<NonNullable<S>>> = R extends any[] ? {
-		[K in keyof R]: R[K] extends { __ctx?: any } ? R[K] : ReturnType<__VLS_FunctionalGeneralComponent<R[K]>>
-	} : R;
-
 	function __VLS_getVForSourceType(source: number): [number, number, number][];
 	function __VLS_getVForSourceType(source: string): [string, number, number][];
 	function __VLS_getVForSourceType<T extends any[]>(source: T): [
diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts
index b81507671d..d7037e9b3e 100644
--- a/packages/language-core/lib/codegen/template/element.ts
+++ b/packages/language-core/lib/codegen/template/element.ts
@@ -307,6 +307,12 @@ export function* generateElement(
 		: undefined;
 	const failedPropExps: FailedPropExpression[] = [];
 
+	ctx.currentComponent?.childNodes.push({
+		name: `__VLS_nativeElements.${node.tag}`,
+		start: node.loc.start.offset,
+		end: node.loc.end.offset
+	});
+
 	yield `__VLS_asFunctionalElement(__VLS_intrinsicElements`;
 	yield* generatePropertyAccess(
 		options,
diff --git a/test-workspace/tsc/passedFixtures/vue3/slot-children/main.vue b/test-workspace/tsc/passedFixtures/vue3/slot-children/main.vue
index ced9291a8c..f5e3309405 100644
--- a/test-workspace/tsc/passedFixtures/vue3/slot-children/main.vue
+++ b/test-workspace/tsc/passedFixtures/vue3/slot-children/main.vue
@@ -11,5 +11,9 @@ const foo = {} as 'a' | 'b';
 		<Child :foo="(`b` as const)" />
 		<!-- @vue-expect-error -->
 		<Child :foo="(`c` as const)" /> 
+
+		<a></a>
+		<!-- @vue-expect-error -->
+		<img />
 	</Parent>
 </template>
diff --git a/test-workspace/tsc/passedFixtures/vue3/slot-children/parent.vue b/test-workspace/tsc/passedFixtures/vue3/slot-children/parent.vue
index 5f97ffb139..109f6db0a5 100644
--- a/test-workspace/tsc/passedFixtures/vue3/slot-children/parent.vue
+++ b/test-workspace/tsc/passedFixtures/vue3/slot-children/parent.vue
@@ -5,6 +5,6 @@ defineProps<{
 	foo: T;
 }>();
 defineSlots<{
-	default?(): ReturnType<typeof Child<T>>[];
+	default?(): (ReturnType<typeof Child<T>> | HTMLAnchorElement)[];
 }>();
 </script>