From d8303107fbbd986b0234dc05268e4f76bda2d4d6 Mon Sep 17 00:00:00 2001 From: Harvmaster Date: Wed, 12 Aug 2026 00:28:01 +0000 Subject: [PATCH] Fix prop typing --- packages/core-v2/src/scene.test.ts | 10 ++++++++++ packages/core-v2/src/scene.ts | 9 +++++---- packages/core-v2/src/types.ts | 14 +++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/core-v2/src/scene.test.ts b/packages/core-v2/src/scene.test.ts index e95fbff..e63e594 100644 --- a/packages/core-v2/src/scene.test.ts +++ b/packages/core-v2/src/scene.test.ts @@ -205,8 +205,15 @@ describe("origin-relative scene graph", () => { let xMounts = 0; let xUnmounts = 0; let yUnmounts = 0; + const X = defineComponent({ name: "X", + props: { + message: { + type: String, + required: true, + }, + }, setup() { onMounted(() => { xMounts += 1; @@ -214,6 +221,9 @@ describe("origin-relative scene graph", () => { onUnmounted(() => { xUnmounts += 1; }); + defineProps<{ + message: string; + }>(); return () => h( "div", diff --git a/packages/core-v2/src/scene.ts b/packages/core-v2/src/scene.ts index aaa9395..50c645b 100644 --- a/packages/core-v2/src/scene.ts +++ b/packages/core-v2/src/scene.ts @@ -24,6 +24,7 @@ import type { OriginSceneNode, OriginSceneNodeState, OriginView, + PropsOf, } from "./types"; interface SceneNodeState { @@ -79,12 +80,12 @@ let viewSequence = 0; * ``` */ export function originView< - Props extends Record = Record, + T extends Component = Component, >( - component: Component, - props?: Props, + component: T, + props?: PropsOf, options: OriginViewOptions = {}, -): OriginView { +): OriginView { const inferredName = options.name ?? (typeof component === "object" && "name" in component diff --git a/packages/core-v2/src/types.ts b/packages/core-v2/src/types.ts index 26798c0..8975b3b 100644 --- a/packages/core-v2/src/types.ts +++ b/packages/core-v2/src/types.ts @@ -1,5 +1,12 @@ import type { Component, ComputedRef, CSSProperties, ShallowRef } from "vue"; +export type PropsOf = + T extends abstract new (...args: any[]) => { $props: infer P } + ? P + : T extends (props: infer P, ...args: any[]) => any + ? P + : never; + /** * A view is a recipe for creating a Vue component, not a mounted instance. * @@ -9,12 +16,13 @@ import type { Component, ComputedRef, CSSProperties, ShallowRef } from "vue"; * @typeParam Props - The props accepted by the component recipe. */ export interface OriginView< - Props extends Record = Record, + T extends Component = Component, + // Props extends Record = Record, > { /** The Vue component definition that will be mounted for this recipe. */ - readonly component: Component; + readonly component: T; /** Props passed to the component when the recipe is mounted. */ - readonly props?: Readonly; + readonly props?: Readonly>; /** * A developer-facing recipe identity used in diagnostics and as the prefix * of generated scene-node keys. It does not make Vue reuse an instance.