浏览代码

types(runtime-vapor): add types for Vapor components (#14400)

zhiyuanzmj 2 月之前
父节点
当前提交
0070b45f83

+ 33 - 1
packages-private/dts-test/vapor/defineVaporComponent.test-d.tsx

@@ -9,7 +9,11 @@ import {
   type GenericComponentInstance,
   type PropType,
   type VaporComponentInstance,
+  VaporKeepAlive,
   type VaporPublicProps,
+  VaporTeleport,
+  VaporTransition,
+  VaporTransitionGroup,
   createApp,
   createComponent,
   createVaporApp,
@@ -1056,11 +1060,40 @@ describe('expose typing', () => {
   expectType<string>(bar.exposeProxy!.b)
 })
 
+describe('Custom options', () => {
+  defineVaporComponent({
+    customOption: 'foo',
+  })
+})
+
+describe('VaporTeleport props', () => {
+  ;<VaporTeleport to="body" disabled defer />
+})
+
+describe('VaporKeepAlive props', () => {
+  ;<VaporKeepAlive include={['foo']} exclude={['bar']} max={10} />
+})
+
+describe('Transition props', () => {
+  ;<VaporTransition name="foo" type="transition" css duration={10} />
+})
+
+describe('TransitionGroup props', () => {
+  ;<VaporTransitionGroup
+    tag="div"
+    name="foo"
+    type="transition"
+    css
+    duration={10}
+  />
+})
+
 // code generated by tsc / vue-tsc, make sure this continues to work
 // so we don't accidentally change the args order of DefineComponent
 declare const MyButton: DefineVaporComponent<
   {},
   string,
+  Readonly<ExtractPropTypes<{}>>,
   EmitsOptions,
   string,
   {},
@@ -1068,7 +1101,6 @@ declare const MyButton: DefineVaporComponent<
   Block,
   {},
   true,
-  Readonly<ExtractPropTypes<{}>>,
   VaporPublicProps & AllowedComponentProps & ComponentCustomProps,
   {},
   {}

+ 2 - 2
packages/runtime-vapor/__tests__/_utils.ts

@@ -1,9 +1,9 @@
 import { createVaporApp, vaporInteropPlugin } from '../src'
 import { type App, type Component, createApp } from '@vue/runtime-dom'
 import type {
-  ObjectVaporComponent,
   VaporComponent,
   VaporComponentInstance,
+  VaporComponentOptions,
 } from '../src/component'
 import type { RawProps } from '../src/componentProps'
 import { compileScript, parse } from '@vue/compiler-sfc'
@@ -198,7 +198,7 @@ export function compile(
 export function compileToVaporRender(
   template: string,
   options?: CompilerOptions,
-): ObjectVaporComponent['render'] {
+): VaporComponentOptions['render'] {
   let { code } = compileVapor(template, {
     mode: 'module',
     prefixIdentifiers: true,

+ 1 - 1
packages/runtime-vapor/__tests__/components/KeepAlive.spec.ts

@@ -14,7 +14,7 @@ import {
 } from 'vue'
 import type { LooseRawProps, VaporComponent } from '../../src/component'
 import { makeRender } from '../_utils'
-import { VaporKeepAliveImpl as VaporKeepAlive } from '../../src/components/KeepAlive'
+import { VaporKeepAlive } from '../../src/components/KeepAlive'
 import {
   child,
   createComponent,

+ 14 - 12
packages/runtime-vapor/src/apiDefineComponent.ts

@@ -1,4 +1,4 @@
-import type { ObjectVaporComponent, VaporComponentInstance } from './component'
+import type { VaporComponentInstance, VaporComponentOptions } from './component'
 import {
   type IsKeyValues,
   type Prettify,
@@ -38,6 +38,11 @@ type VaporComponentInstanceConstructor<T extends VaporComponentInstance> = {
 export type DefineVaporComponent<
   RuntimePropsOptions = {},
   RuntimePropsKeys extends string = string,
+  InferredProps = string extends RuntimePropsKeys
+    ? ComponentObjectPropsOptions extends RuntimePropsOptions
+      ? {}
+      : ExtractPropTypes<RuntimePropsOptions>
+    : { [key in RuntimePropsKeys]?: any },
   Emits extends EmitsOptions = {},
   RuntimeEmitsKeys extends string = string,
   Slots extends StaticSlots = StaticSlots,
@@ -45,11 +50,6 @@ export type DefineVaporComponent<
   TypeBlock extends Block = Block,
   TypeRefs extends Record<string, unknown> = {},
   MakeDefaultsOptional extends boolean = true,
-  InferredProps = string extends RuntimePropsKeys
-    ? ComponentObjectPropsOptions extends RuntimePropsOptions
-      ? {}
-      : ExtractPropTypes<RuntimePropsOptions>
-    : { [key in RuntimePropsKeys]?: any },
   PublicProps = VaporPublicProps,
   ResolvedProps = InferredProps & EmitsToProps<Emits>,
   Defaults = ExtractDefaultPropTypes<RuntimePropsOptions>,
@@ -68,7 +68,7 @@ export type DefineVaporComponent<
     TypeRefs
   >
 > &
-  ObjectVaporComponent<
+  VaporComponentOptions<
     RuntimePropsOptions | RuntimePropsKeys[],
     Emits,
     RuntimeEmitsKeys,
@@ -108,7 +108,7 @@ export function defineVaporComponent<
       expose: (exposed: Exposed) => void
     },
   ) => VaporRenderResult<TypeBlock> | void,
-  extraOptions?: ObjectVaporComponent<
+  extraOptions?: VaporComponentOptions<
     (keyof Props)[],
     Emits,
     RuntimeEmitsKeys,
@@ -134,7 +134,7 @@ export function defineVaporComponent<
       expose: (exposed: Exposed) => void
     },
   ) => VaporRenderResult<TypeBlock> | void,
-  extraOptions?: ObjectVaporComponent<
+  extraOptions?: VaporComponentOptions<
     ComponentObjectPropsOptions<Props>,
     Emits,
     RuntimeEmitsKeys,
@@ -171,7 +171,7 @@ export function defineVaporComponent<
   TypeRefs extends Record<string, unknown> = {},
   TypeBlock extends Block = Block,
 >(
-  options: ObjectVaporComponent<
+  options: VaporComponentOptions<
     RuntimePropsOptions | RuntimePropsKeys[],
     ResolvedEmits,
     RuntimeEmitsKeys,
@@ -180,6 +180,8 @@ export function defineVaporComponent<
     TypeBlock,
     InferredProps
   > & {
+    // allow any custom options
+    [key: string]: any
     /**
      * @private for language-tools use only
      */
@@ -200,6 +202,7 @@ export function defineVaporComponent<
 ): DefineVaporComponent<
   RuntimePropsOptions,
   RuntimePropsKeys,
+  InferredProps,
   ResolvedEmits,
   RuntimeEmitsKeys,
   Slots,
@@ -208,8 +211,7 @@ export function defineVaporComponent<
   TypeRefs,
   // MakeDefaultsOptional - if TypeProps is provided, set to false to use
   // user props types verbatim
-  unknown extends TypeProps ? true : false,
-  InferredProps
+  unknown extends TypeProps ? true : false
 >
 
 /*@__NO_SIDE_EFFECTS__*/

+ 5 - 5
packages/runtime-vapor/src/apiDefineCustomElement.ts

@@ -17,9 +17,9 @@ import {
   warn,
 } from '@vue/runtime-dom'
 import type {
-  ObjectVaporComponent,
   VaporComponent,
   VaporComponentInstance,
+  VaporComponentOptions,
 } from './component'
 import type { Block } from './block'
 import { withHydration } from './dom/hydration'
@@ -46,7 +46,7 @@ export function defineVaporCustomElement<Props, RawBindings = object>(
       expose: (exposed: Record<string, any>) => void
     },
   ) => RawBindings | VaporRenderResult,
-  options?: Pick<ObjectVaporComponent, 'name' | 'inheritAttrs' | 'emits'> &
+  options?: Pick<VaporComponentOptions, 'name' | 'inheritAttrs' | 'emits'> &
     CustomElementOptions & {
       props?: (keyof Props)[]
     },
@@ -61,7 +61,7 @@ export function defineVaporCustomElement<Props, RawBindings = object>(
       expose: (exposed: Record<string, any>) => void
     },
   ) => RawBindings | VaporRenderResult,
-  options?: Pick<ObjectVaporComponent, 'name' | 'inheritAttrs' | 'emits'> &
+  options?: Pick<VaporComponentOptions, 'name' | 'inheritAttrs' | 'emits'> &
     CustomElementOptions & {
       props?: ComponentObjectPropsOptions<Props>
     },
@@ -141,7 +141,7 @@ export function defineVaporCustomElement<
 /*@__NO_SIDE_EFFECTS__*/
 export function defineVaporCustomElement(
   options: any,
-  extraOptions?: Omit<ObjectVaporComponent, 'setup'> & CustomElementOptions,
+  extraOptions?: Omit<VaporComponentOptions, 'setup'> & CustomElementOptions,
   /**
    * @internal
    */
@@ -162,7 +162,7 @@ export function defineVaporCustomElement(
 /*@__NO_SIDE_EFFECTS__*/
 export const defineVaporSSRCustomElement = ((
   options: any,
-  extraOptions?: Omit<ObjectVaporComponent, 'setup'>,
+  extraOptions?: Omit<VaporComponentOptions, 'setup'>,
 ) => {
   // @ts-expect-error
   return defineVaporCustomElement(options, extraOptions, createVaporSSRApp)

+ 7 - 4
packages/runtime-vapor/src/component.ts

@@ -127,7 +127,7 @@ export { currentInstance } from '@vue/runtime-dom'
 
 export type VaporComponent =
   | FunctionalVaporComponent
-  | ObjectVaporComponent
+  | VaporComponentOptions
   | DefineVaporComponent
 
 export type FunctionalVaporComponent<
@@ -145,13 +145,13 @@ export type FunctionalVaporComponent<
   },
 ) => VaporRenderResult) &
   Omit<
-    ObjectVaporComponent<ComponentPropsOptions<Props>, Emits, string, Slots>,
+    VaporComponentOptions<ComponentPropsOptions<Props>, Emits, string, Slots>,
     'setup'
   > & {
     displayName?: string
   } & SharedInternalOptions
 
-export interface ObjectVaporComponent<
+export interface VaporComponentOptions<
   Props = {},
   Emits extends EmitsOptions = {},
   RuntimeEmitsKeys extends string = string,
@@ -164,7 +164,10 @@ export interface ObjectVaporComponent<
 >
   extends
     ComponentInternalOptions,
-    AsyncComponentInternalOptions<ObjectVaporComponent, VaporComponentInstance>,
+    AsyncComponentInternalOptions<
+      VaporComponentOptions,
+      VaporComponentInstance
+    >,
     SharedInternalOptions {
   inheritAttrs?: boolean
   props?: Props

+ 12 - 10
packages/runtime-vapor/src/components/KeepAlive.ts

@@ -21,12 +21,14 @@ import {
 } from '@vue/runtime-dom'
 import { type Block, move, remove } from '../block'
 import {
-  type ObjectVaporComponent,
   type VaporComponent,
   type VaporComponentInstance,
   isVaporComponent,
 } from '../component'
-import { defineVaporComponent } from '../apiDefineComponent'
+import {
+  type DefineVaporComponent,
+  defineVaporComponent,
+} from '../apiDefineComponent'
 import {
   ShapeFlags,
   invokeArrayFns,
@@ -38,7 +40,7 @@ import { createElement } from '../dom/node'
 import { type VaporFragment, isDynamicFragment, isFragment } from '../fragment'
 import type { EffectScope } from '@vue/reactivity'
 
-export interface KeepAliveContext {
+export interface VaporKeepAliveContext {
   processShapeFlag(block: Block): boolean
   cacheBlock(): void
   cacheScope(key: any, scope: EffectScope): void
@@ -46,11 +48,11 @@ export interface KeepAliveContext {
   setCurrentBranchKey(key: any): any
 }
 
-export let currentKeepAliveCtx: KeepAliveContext | null = null
+export let currentKeepAliveCtx: VaporKeepAliveContext | null = null
 
 export function setCurrentKeepAliveCtx(
-  ctx: KeepAliveContext | null,
-): KeepAliveContext | null {
+  ctx: VaporKeepAliveContext | null,
+): VaporKeepAliveContext | null {
   try {
     return currentKeepAliveCtx
   } finally {
@@ -106,7 +108,7 @@ function getCompositeKey(
   return composite
 }
 
-const KeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
+const VaporKeepAliveImpl = defineVaporComponent({
   name: 'VaporKeepAlive',
   __isKeepAlive: true,
   props: {
@@ -300,7 +302,7 @@ const KeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
       keptAliveScopes.clear()
     })
 
-    const keepAliveCtx: KeepAliveContext = {
+    const keepAliveCtx: VaporKeepAliveContext = {
       processShapeFlag,
       cacheBlock,
       cacheScope(key, scope) {
@@ -340,8 +342,8 @@ const KeepAliveImpl: ObjectVaporComponent = defineVaporComponent({
   },
 })
 
-export const VaporKeepAliveImpl: ObjectVaporComponent =
-  /*@__PURE__*/ KeepAliveImpl
+export const VaporKeepAlive: DefineVaporComponent<{}, string, KeepAliveProps> =
+  VaporKeepAliveImpl
 
 const shouldCache = (
   block: GenericComponentInstance | VaporFragment,

+ 5 - 1
packages/runtime-vapor/src/components/Teleport.ts

@@ -37,8 +37,9 @@ import {
   runWithoutHydration,
   setCurrentHydrationNode,
 } from '../dom/hydration'
+import type { DefineVaporSetupFnComponent } from '../apiDefineComponent'
 
-export const VaporTeleportImpl = {
+const VaporTeleportImpl = {
   name: 'VaporTeleport',
   __isTeleport: true,
   __vapor: true,
@@ -349,6 +350,9 @@ export class TeleportFragment extends VaporFragment {
   }
 }
 
+export const VaporTeleport =
+  VaporTeleportImpl as unknown as DefineVaporSetupFnComponent<TeleportProps>
+
 /**
  * Use duck typing to check for VaporTeleport instead of direct reference
  * to VaporTeleportImpl, allowing tree-shaking when Teleport is not used.

+ 13 - 7
packages/runtime-vapor/src/components/TransitionGroup.ts

@@ -29,24 +29,27 @@ import {
   setTransitionHooksOnFragment,
 } from './Transition'
 import {
-  type ObjectVaporComponent,
   type VaporComponentInstance,
+  type VaporComponentOptions,
   isVaporComponent,
 } from '../component'
 import { isForBlock } from '../apiCreateFor'
 import { createElement } from '../dom/node'
 import { isFragment } from '../fragment'
+import {
+  type DefineVaporComponent,
+  defineVaporComponent,
+} from '../apiDefineComponent'
 
 const positionMap = new WeakMap<TransitionBlock, DOMRect>()
 const newPositionMap = new WeakMap<TransitionBlock, DOMRect>()
 
-const decorate = <T extends ObjectVaporComponent>(t: T): T => {
+const decorate = <T extends VaporComponentOptions>(t: T): T => {
   delete (t.props! as any).mode
-  t.__vapor = true
   return t
 }
 
-const VaporTransitionGroupImpl: ObjectVaporComponent = {
+const VaporTransitionGroupImpl = defineVaporComponent({
   name: 'VaporTransitionGroup',
 
   props: /*@__PURE__*/ extend({}, TransitionPropsValidators, {
@@ -169,10 +172,13 @@ const VaporTransitionGroupImpl: ObjectVaporComponent = {
       return slottedBlock
     }
   },
-}
+})
 
-export const VaporTransitionGroup: ObjectVaporComponent =
-  /*@__PURE__*/ decorate(VaporTransitionGroupImpl)
+export const VaporTransitionGroup: DefineVaporComponent<
+  {},
+  string,
+  TransitionGroupProps
+> = /*@__PURE__*/ decorate(VaporTransitionGroupImpl)
 
 function getTransitionBlocks(block: Block) {
   let children: TransitionBlock[] = []

+ 2 - 2
packages/runtime-vapor/src/fragment.ts

@@ -38,7 +38,7 @@ import { isArray } from '@vue/shared'
 import { renderEffect } from './renderEffect'
 import { currentSlotOwner, setCurrentSlotOwner } from './componentSlots'
 import {
-  type KeepAliveContext,
+  type VaporKeepAliveContext,
   currentKeepAliveCtx,
   setCurrentKeepAliveCtx,
 } from './components/KeepAlive'
@@ -95,7 +95,7 @@ export class DynamicFragment extends VaporFragment {
   // set ref for async wrapper
   setAsyncRef?: (instance: VaporComponentInstance) => void
 
-  keepAliveCtx: KeepAliveContext | null
+  keepAliveCtx: VaporKeepAliveContext | null
 
   slotOwner: VaporComponentInstance | null
 

+ 3 - 3
packages/runtime-vapor/src/index.ts

@@ -9,8 +9,8 @@ export {
 export { defineVaporAsyncComponent } from './apiDefineAsyncComponent'
 export { vaporInteropPlugin } from './vdomInterop'
 export type { VaporDirective } from './directives/custom'
-export { VaporTeleportImpl as VaporTeleport } from './components/Teleport'
-export { VaporKeepAliveImpl as VaporKeepAlive } from './components/KeepAlive'
+export { VaporTeleport } from './components/Teleport'
+export { VaporKeepAlive } from './components/KeepAlive'
 export {
   defineVaporCustomElement,
   defineVaporSSRCustomElement,
@@ -78,6 +78,6 @@ export { VaporTransition } from './components/Transition'
 export { VaporTransitionGroup } from './components/TransitionGroup'
 
 // types
-export type { VaporComponent } from './component'
+export type { VaporComponent, VaporComponentOptions } from './component'
 export type { VaporSlot } from './componentSlots'
 export type { VaporTransitionHooks } from './block'