From 217e1e6f86a6bea192af0d0163368d28edaa0a34 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 10 Dec 2024 15:50:49 +0800 Subject: [PATCH] wip(vapor): make createComponent rawProps/rawSlots accept wider types for internal use --- packages/runtime-vapor/src/component.ts | 29 ++++++++++++++++---- packages/runtime-vapor/src/componentProps.ts | 2 +- packages/runtime-vapor/src/componentSlots.ts | 3 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index f544809b7..18fe296e2 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -27,6 +27,7 @@ import { type Block, insert, isBlock, remove } from './block' import { pauseTracking, proxyRefs, resetTracking } from '@vue/reactivity' import { EMPTY_OBJ, invokeArrayFns, isFunction, isString } from '@vue/shared' import { + type DynamicPropsSource, type RawProps, getPropsProxyHandlers, hasFallthroughAttrs, @@ -39,6 +40,7 @@ import { emit, normalizeEmitsOptions } from './componentEmits' import { setStyle } from './dom/style' import { setClass, setDynamicProp } from './dom/prop' import { + type DynamicSlotSource, type RawSlots, type Slot, type StaticSlots, @@ -97,10 +99,25 @@ interface SharedInternalOptions { __emitsOptions?: ObjectEmitsOptions } +// In TypeScript, it is actually impossible to have a record type with only +// specific properties that have a different type from the indexed type. +// This makes our rawProps / rawSlots shape difficult to satisfy when calling +// `createComponent` - luckily this is not user-facing, so we don't need to be +// 100% strict. Here we use intentionally wider types to make `createComponent` +// more ergonomic in tests and internal call sites, where we immediately cast +// them into the stricter types. +type LooseRawProps = Record unknown) | DynamicPropsSource[]> & { + $?: DynamicPropsSource[] +} + +type LooseRawSlots = Record & { + $?: DynamicSlotSource[] +} + export function createComponent( component: VaporComponent, - rawProps?: RawProps | null, - rawSlots?: RawSlots | null, + rawProps?: LooseRawProps | null, + rawSlots?: LooseRawSlots | null, isSingleRoot?: boolean, appContext?: GenericAppContext, ): VaporComponentInstance { @@ -114,7 +131,9 @@ export function createComponent( ) { const attrs = currentInstance.attrs if (rawProps) { - ;(rawProps.$ || (rawProps.$ = [])).push(() => attrs) + ;((rawProps as RawProps).$ || ((rawProps as RawProps).$ = [])).push( + () => attrs, + ) } else { rawProps = { $: [() => attrs] } as RawProps } @@ -122,8 +141,8 @@ export function createComponent( const instance = new VaporComponentInstance( component, - rawProps, - rawSlots, + rawProps as RawProps, + rawSlots as RawSlots, appContext, ) diff --git a/packages/runtime-vapor/src/componentProps.ts b/packages/runtime-vapor/src/componentProps.ts index 501770674..1e615b578 100644 --- a/packages/runtime-vapor/src/componentProps.ts +++ b/packages/runtime-vapor/src/componentProps.ts @@ -28,7 +28,7 @@ export type RawProps = Record unknown> & { $?: DynamicPropsSource[] } -type DynamicPropsSource = +export type DynamicPropsSource = | (() => Record) | Record unknown> diff --git a/packages/runtime-vapor/src/componentSlots.ts b/packages/runtime-vapor/src/componentSlots.ts index d33d76bce..4ee382840 100644 --- a/packages/runtime-vapor/src/componentSlots.ts +++ b/packages/runtime-vapor/src/componentSlots.ts @@ -10,7 +10,7 @@ import type { VaporComponentInstance } from './component' import { renderEffect } from './renderEffect' export type RawSlots = Record & { - $?: (StaticSlots | DynamicSlotFn)[] + $?: DynamicSlotSource[] } export type StaticSlots = Record @@ -18,6 +18,7 @@ export type StaticSlots = Record export type Slot = BlockFn export type DynamicSlot = { name: string; fn: Slot } export type DynamicSlotFn = () => DynamicSlot | DynamicSlot[] +export type DynamicSlotSource = StaticSlots | DynamicSlotFn export const dynamicSlotsProxyHandlers: ProxyHandler = { get: getSlot,