From: Evan You Date: Tue, 10 Dec 2024 07:50:49 +0000 (+0800) Subject: wip(vapor): make createComponent rawProps/rawSlots accept wider types for internal use X-Git-Tag: v3.6.0-alpha.1~16^2~174 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=217e1e6f86a6bea192af0d0163368d28edaa0a34;p=thirdparty%2Fvuejs%2Fcore.git wip(vapor): make createComponent rawProps/rawSlots accept wider types for internal use --- diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index f544809b7d..18fe296e2d 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 501770674b..1e615b5787 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 d33d76bce9..4ee3828402 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,