refactor(types): widen Component
type to include consutructor types
returned from `defineComponent` ref: https://github.com/vuejs/vue-router-next/pull/421 also close #1880 Previous `Component` type is now exported as `ConcreteComponent`. This introduces a minor breaking change when calling `h(comp, { ... })` will now fail if `comp` is a of generic `Component` type, since it does not specify what props it expects.
This commit is contained in:
parent
4baf852a34
commit
eb2ae44d94
@ -11,8 +11,7 @@ import {
|
||||
watch,
|
||||
watchEffect,
|
||||
onUnmounted,
|
||||
onErrorCaptured,
|
||||
Component
|
||||
onErrorCaptured
|
||||
} from '@vue/runtime-test'
|
||||
|
||||
describe('Suspense', () => {
|
||||
@ -31,7 +30,7 @@ describe('Suspense', () => {
|
||||
setup(props: any, { slots }: any) {
|
||||
const p = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(() => h<Component>(comp, props, slots))
|
||||
resolve(() => h(comp, props, slots))
|
||||
}, delay)
|
||||
})
|
||||
// in Node 12, due to timer/nextTick mechanism change, we have to wait
|
||||
|
@ -1,21 +1,19 @@
|
||||
import {
|
||||
PublicAPIComponent,
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
currentInstance,
|
||||
ComponentInternalInstance,
|
||||
isInSSRComponentSetup
|
||||
} from './component'
|
||||
import { isFunction, isObject } from '@vue/shared'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
import { createVNode } from './vnode'
|
||||
import { defineComponent } from './apiDefineComponent'
|
||||
import { warn } from './warning'
|
||||
import { ref } from '@vue/reactivity'
|
||||
import { handleError, ErrorCodes } from './errorHandling'
|
||||
|
||||
export type AsyncComponentResolveResult<T = PublicAPIComponent> =
|
||||
| T
|
||||
| { default: T } // es modules
|
||||
export type AsyncComponentResolveResult<T = Component> = T | { default: T } // es modules
|
||||
|
||||
export type AsyncComponentLoader<T = any> = () => Promise<
|
||||
AsyncComponentResolveResult<T>
|
||||
@ -23,8 +21,8 @@ export type AsyncComponentLoader<T = any> = () => Promise<
|
||||
|
||||
export interface AsyncComponentOptions<T = any> {
|
||||
loader: AsyncComponentLoader<T>
|
||||
loadingComponent?: PublicAPIComponent
|
||||
errorComponent?: PublicAPIComponent
|
||||
loadingComponent?: Component
|
||||
errorComponent?: Component
|
||||
delay?: number
|
||||
timeout?: number
|
||||
suspensible?: boolean
|
||||
@ -37,7 +35,7 @@ export interface AsyncComponentOptions<T = any> {
|
||||
}
|
||||
|
||||
export function defineAsyncComponent<
|
||||
T extends PublicAPIComponent = { new (): ComponentPublicInstance }
|
||||
T extends Component = { new (): ComponentPublicInstance }
|
||||
>(source: AsyncComponentLoader<T> | AsyncComponentOptions<T>): T {
|
||||
if (isFunction(source)) {
|
||||
source = { loader: source }
|
||||
@ -53,8 +51,8 @@ export function defineAsyncComponent<
|
||||
onError: userOnError
|
||||
} = source
|
||||
|
||||
let pendingRequest: Promise<Component> | null = null
|
||||
let resolvedComp: Component | undefined
|
||||
let pendingRequest: Promise<ConcreteComponent> | null = null
|
||||
let resolvedComp: ConcreteComponent | undefined
|
||||
|
||||
let retries = 0
|
||||
const retry = () => {
|
||||
@ -63,8 +61,8 @@ export function defineAsyncComponent<
|
||||
return load()
|
||||
}
|
||||
|
||||
const load = (): Promise<Component> => {
|
||||
let thisRequest: Promise<Component>
|
||||
const load = (): Promise<ConcreteComponent> => {
|
||||
let thisRequest: Promise<ConcreteComponent>
|
||||
return (
|
||||
pendingRequest ||
|
||||
(thisRequest = pendingRequest = loader()
|
||||
@ -135,7 +133,9 @@ export function defineAsyncComponent<
|
||||
onError(err)
|
||||
return () =>
|
||||
errorComponent
|
||||
? createVNode(errorComponent as Component, { error: err })
|
||||
? createVNode(errorComponent as ConcreteComponent, {
|
||||
error: err
|
||||
})
|
||||
: null
|
||||
})
|
||||
}
|
||||
@ -175,11 +175,11 @@ export function defineAsyncComponent<
|
||||
if (loaded.value && resolvedComp) {
|
||||
return createInnerComp(resolvedComp, instance)
|
||||
} else if (error.value && errorComponent) {
|
||||
return createVNode(errorComponent as Component, {
|
||||
return createVNode(errorComponent as ConcreteComponent, {
|
||||
error: error.value
|
||||
})
|
||||
} else if (loadingComponent && !delayed.value) {
|
||||
return createVNode(loadingComponent as Component)
|
||||
return createVNode(loadingComponent as ConcreteComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,7 +187,7 @@ export function defineAsyncComponent<
|
||||
}
|
||||
|
||||
function createInnerComp(
|
||||
comp: Component,
|
||||
comp: ConcreteComponent,
|
||||
{ vnode: { props, children } }: ComponentInternalInstance
|
||||
) {
|
||||
return createVNode(comp, props, children)
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
Data,
|
||||
validateComponentName,
|
||||
PublicAPIComponent
|
||||
Component
|
||||
} from './component'
|
||||
import { ComponentOptions } from './componentOptions'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
import { Directive, validateDirectiveName } from './directives'
|
||||
import { RootRenderFunction } from './renderer'
|
||||
import { InjectionKey } from './apiInject'
|
||||
@ -21,8 +21,8 @@ export interface App<HostElement = any> {
|
||||
config: AppConfig
|
||||
use(plugin: Plugin, ...options: any[]): this
|
||||
mixin(mixin: ComponentOptions): this
|
||||
component(name: string): PublicAPIComponent | undefined
|
||||
component(name: string, component: PublicAPIComponent): this
|
||||
component(name: string): Component | undefined
|
||||
component(name: string, component: Component): this
|
||||
directive(name: string): Directive | undefined
|
||||
directive(name: string, directive: Directive): this
|
||||
mount(
|
||||
@ -33,7 +33,7 @@ export interface App<HostElement = any> {
|
||||
provide<T>(key: InjectionKey<T> | string, value: T): this
|
||||
|
||||
// internal, but we need to expose these for the server-renderer and devtools
|
||||
_component: Component
|
||||
_component: ConcreteComponent
|
||||
_props: Data | null
|
||||
_container: HostElement | null
|
||||
_context: AppContext
|
||||
@ -70,7 +70,7 @@ export interface AppContext {
|
||||
app: App // for devtools
|
||||
config: AppConfig
|
||||
mixins: ComponentOptions[]
|
||||
components: Record<string, PublicAPIComponent>
|
||||
components: Record<string, Component>
|
||||
directives: Record<string, Directive>
|
||||
provides: Record<string | symbol, any>
|
||||
reload?: () => void // HMR only
|
||||
@ -104,7 +104,7 @@ export function createAppContext(): AppContext {
|
||||
}
|
||||
|
||||
export type CreateAppFunction<HostElement> = (
|
||||
rootComponent: PublicAPIComponent,
|
||||
rootComponent: Component,
|
||||
rootProps?: Data | null
|
||||
) => App<HostElement>
|
||||
|
||||
@ -124,7 +124,7 @@ export function createAppAPI<HostElement>(
|
||||
let isMounted = false
|
||||
|
||||
const app: App = (context.app = {
|
||||
_component: rootComponent as Component,
|
||||
_component: rootComponent as ConcreteComponent,
|
||||
_props: rootProps,
|
||||
_container: null,
|
||||
_context: context,
|
||||
@ -177,7 +177,7 @@ export function createAppAPI<HostElement>(
|
||||
return app
|
||||
},
|
||||
|
||||
component(name: string, component?: PublicAPIComponent): any {
|
||||
component(name: string, component?: Component): any {
|
||||
if (__DEV__) {
|
||||
validateComponentName(name, context.config)
|
||||
}
|
||||
@ -208,7 +208,10 @@ export function createAppAPI<HostElement>(
|
||||
|
||||
mount(rootContainer: HostElement, isHydrate?: boolean): any {
|
||||
if (!isMounted) {
|
||||
const vnode = createVNode(rootComponent as Component, rootProps)
|
||||
const vnode = createVNode(
|
||||
rootComponent as ConcreteComponent,
|
||||
rootProps
|
||||
)
|
||||
// store app context on the root VNode.
|
||||
// this will be set on the root instance on initial mount.
|
||||
vnode.appContext = context
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
import {
|
||||
CreateComponentPublicInstance,
|
||||
ComponentPublicInstanceConstructor
|
||||
} from './componentProxy'
|
||||
} from './componentPublicInstance'
|
||||
import { ExtractPropTypes, ComponentPropsOptions } from './componentProps'
|
||||
import { EmitsOptions } from './componentEmits'
|
||||
import { isFunction } from '@vue/shared'
|
||||
@ -205,7 +205,5 @@ export function defineComponent<
|
||||
|
||||
// implementation, close to no-op
|
||||
export function defineComponent(options: unknown) {
|
||||
return isFunction(options)
|
||||
? { setup: options, name: options.name }
|
||||
: options
|
||||
return isFunction(options) ? { setup: options, name: options.name } : options
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
setCurrentInstance,
|
||||
isInSSRComponentSetup
|
||||
} from './component'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling'
|
||||
import { warn } from './warning'
|
||||
import { capitalize } from '@vue/shared'
|
||||
|
@ -7,14 +7,14 @@ import {
|
||||
proxyRefs
|
||||
} from '@vue/reactivity'
|
||||
import {
|
||||
CreateComponentPublicInstance,
|
||||
ComponentPublicInstance,
|
||||
PublicInstanceProxyHandlers,
|
||||
RuntimeCompiledPublicInstanceProxyHandlers,
|
||||
createRenderContext,
|
||||
exposePropsOnRenderContext,
|
||||
exposeSetupStateOnRenderContext
|
||||
} from './componentProxy'
|
||||
exposeSetupStateOnRenderContext,
|
||||
ComponentPublicInstanceConstructor
|
||||
} from './componentPublicInstance'
|
||||
import {
|
||||
ComponentPropsOptions,
|
||||
NormalizedPropsOptions,
|
||||
@ -110,21 +110,19 @@ export interface ClassComponent {
|
||||
__vccOpts: ComponentOptions
|
||||
}
|
||||
|
||||
export type Component = ComponentOptions | FunctionalComponent<any, any>
|
||||
/**
|
||||
* Concrete component type matches its actual value: it's either an options
|
||||
* object, or a function. Use this where the code expects to work with actual
|
||||
* values, e.g. checking if its a function or not. This is mostly for internal
|
||||
* implementation code.
|
||||
*/
|
||||
export type ConcreteComponent = ComponentOptions | FunctionalComponent<any, any>
|
||||
|
||||
// A type used in public APIs where a component type is expected.
|
||||
// The constructor type is an artificial type returned by defineComponent().
|
||||
export type PublicAPIComponent =
|
||||
| Component
|
||||
| {
|
||||
new (...args: any[]): CreateComponentPublicInstance<
|
||||
any,
|
||||
any,
|
||||
any,
|
||||
any,
|
||||
any
|
||||
>
|
||||
}
|
||||
/**
|
||||
* A type used in public APIs where a component type is expected.
|
||||
* The constructor type is an artificial type returned by defineComponent().
|
||||
*/
|
||||
export type Component = ConcreteComponent | ComponentPublicInstanceConstructor
|
||||
|
||||
export { ComponentOptions }
|
||||
|
||||
@ -174,7 +172,7 @@ export type InternalRenderFunction = {
|
||||
*/
|
||||
export interface ComponentInternalInstance {
|
||||
uid: number
|
||||
type: Component
|
||||
type: ConcreteComponent
|
||||
parent: ComponentInternalInstance | null
|
||||
root: ComponentInternalInstance
|
||||
appContext: AppContext
|
||||
@ -346,7 +344,7 @@ export function createComponentInstance(
|
||||
parent: ComponentInternalInstance | null,
|
||||
suspense: SuspenseBoundary | null
|
||||
) {
|
||||
const type = vnode.type as Component
|
||||
const type = vnode.type as ConcreteComponent
|
||||
// inherit parent app context - or - if root, adopt from root vnode
|
||||
const appContext =
|
||||
(parent ? parent.appContext : vnode.appContext) || emptyAppContext
|
||||
@ -703,7 +701,7 @@ const classify = (str: string): string =>
|
||||
/* istanbul ignore next */
|
||||
export function formatComponentName(
|
||||
instance: ComponentInternalInstance | null,
|
||||
Component: Component,
|
||||
Component: ConcreteComponent,
|
||||
isRoot = false
|
||||
): string {
|
||||
let name = isFunction(Component)
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
isFunction,
|
||||
extend
|
||||
} from '@vue/shared'
|
||||
import { ComponentInternalInstance, Component } from './component'
|
||||
import { ComponentInternalInstance, ConcreteComponent } from './component'
|
||||
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
||||
import { warn } from './warning'
|
||||
import { normalizePropsOptions } from './componentProps'
|
||||
@ -94,7 +94,7 @@ export function emit(
|
||||
}
|
||||
|
||||
function normalizeEmitsOptions(
|
||||
comp: Component
|
||||
comp: ConcreteComponent
|
||||
): ObjectEmitsOptions | undefined {
|
||||
if (hasOwn(comp, '__emits')) {
|
||||
return comp.__emits
|
||||
@ -131,7 +131,7 @@ function normalizeEmitsOptions(
|
||||
// Check if an incoming prop key is a declared emit event listener.
|
||||
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
|
||||
// both considered matched listeners.
|
||||
export function isEmitListener(comp: Component, key: string): boolean {
|
||||
export function isEmitListener(comp: ConcreteComponent, key: string): boolean {
|
||||
let emits: ObjectEmitsOptions | undefined
|
||||
if (!isOn(key) || !(emits = normalizeEmitsOptions(comp))) {
|
||||
return false
|
||||
|
@ -3,8 +3,8 @@ import {
|
||||
Data,
|
||||
SetupContext,
|
||||
ComponentInternalOptions,
|
||||
PublicAPIComponent,
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
InternalRenderFunction
|
||||
} from './component'
|
||||
import {
|
||||
@ -52,7 +52,7 @@ import { Directive } from './directives'
|
||||
import {
|
||||
CreateComponentPublicInstance,
|
||||
ComponentPublicInstance
|
||||
} from './componentProxy'
|
||||
} from './componentPublicInstance'
|
||||
import { warn } from './warning'
|
||||
import { VNodeChild } from './vnode'
|
||||
|
||||
@ -103,7 +103,7 @@ export interface ComponentOptionsBase<
|
||||
// Luckily `render()` doesn't need any arguments nor does it care about return
|
||||
// type.
|
||||
render?: Function
|
||||
components?: Record<string, PublicAPIComponent>
|
||||
components?: Record<string, Component>
|
||||
directives?: Record<string, Directive>
|
||||
inheritAttrs?: boolean
|
||||
emits?: (E | EE[]) & ThisType<void>
|
||||
@ -132,7 +132,7 @@ export interface ComponentOptionsBase<
|
||||
* marker for AsyncComponentWrapper
|
||||
* @internal
|
||||
*/
|
||||
__asyncLoader?: () => Promise<Component>
|
||||
__asyncLoader?: () => Promise<ConcreteComponent>
|
||||
/**
|
||||
* cache for merged $options
|
||||
* @internal
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
Data,
|
||||
ComponentInternalInstance,
|
||||
ComponentOptions,
|
||||
Component
|
||||
ConcreteComponent
|
||||
} from './component'
|
||||
import { isEmitListener } from './componentEmits'
|
||||
import { InternalObjectKey } from './vnode'
|
||||
@ -310,7 +310,7 @@ function resolvePropValue(
|
||||
}
|
||||
|
||||
export function normalizePropsOptions(
|
||||
comp: Component
|
||||
comp: ConcreteComponent
|
||||
): NormalizedPropsOptions | [] {
|
||||
if (comp.__props) {
|
||||
return comp.__props
|
||||
@ -411,7 +411,7 @@ function getTypeIndex(
|
||||
/**
|
||||
* dev only
|
||||
*/
|
||||
function validateProps(props: Data, comp: Component) {
|
||||
function validateProps(props: Data, comp: ConcreteComponent) {
|
||||
const rawValues = toRaw(props)
|
||||
const options = normalizePropsOptions(comp)[0]
|
||||
for (const key in options) {
|
||||
|
@ -101,6 +101,15 @@ type UnwrapMixinsType<
|
||||
|
||||
type EnsureNonVoid<T> = T extends void ? {} : T
|
||||
|
||||
export type ComponentPublicInstanceConstructor<
|
||||
T extends ComponentPublicInstance = ComponentPublicInstance<any>
|
||||
> = {
|
||||
__isFragment?: never
|
||||
__isTeleport?: never
|
||||
__isSuspense?: never
|
||||
new (): T
|
||||
}
|
||||
|
||||
export type CreateComponentPublicInstance<
|
||||
P = {},
|
||||
B = {},
|
||||
@ -162,12 +171,6 @@ export type ComponentPublicInstance<
|
||||
M &
|
||||
ComponentCustomProperties
|
||||
|
||||
export type ComponentPublicInstanceConstructor<
|
||||
T extends ComponentPublicInstance
|
||||
> = {
|
||||
new (): T
|
||||
}
|
||||
|
||||
type PublicPropertiesMap = Record<string, (i: ComponentInternalInstance) => any>
|
||||
|
||||
const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
|
@ -1,5 +1,5 @@
|
||||
import {
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
getCurrentInstance,
|
||||
FunctionalComponent,
|
||||
SetupContext,
|
||||
@ -33,7 +33,7 @@ import {
|
||||
invokeVNodeHook
|
||||
} from '../renderer'
|
||||
import { setTransitionHooks } from './BaseTransition'
|
||||
import { ComponentRenderContext } from '../componentProxy'
|
||||
import { ComponentRenderContext } from '../componentPublicInstance'
|
||||
|
||||
type MatchPattern = string | RegExp | string[] | RegExp[]
|
||||
|
||||
@ -43,7 +43,7 @@ export interface KeepAliveProps {
|
||||
max?: number | string
|
||||
}
|
||||
|
||||
type CacheKey = string | number | Component
|
||||
type CacheKey = string | number | ConcreteComponent
|
||||
type Cache = Map<CacheKey, VNode>
|
||||
type Keys = Set<CacheKey>
|
||||
|
||||
@ -151,7 +151,7 @@ const KeepAliveImpl = {
|
||||
|
||||
function pruneCache(filter?: (name: string) => boolean) {
|
||||
cache.forEach((vnode, key) => {
|
||||
const name = getName(vnode.type as Component)
|
||||
const name = getName(vnode.type as ConcreteComponent)
|
||||
if (name && (!filter || !filter(name))) {
|
||||
pruneCacheEntry(key)
|
||||
}
|
||||
@ -228,7 +228,7 @@ const KeepAliveImpl = {
|
||||
return vnode
|
||||
}
|
||||
|
||||
const comp = vnode.type as Component
|
||||
const comp = vnode.type as ConcreteComponent
|
||||
const name = getName(comp)
|
||||
const { include, exclude, max } = props
|
||||
|
||||
@ -291,7 +291,7 @@ export const KeepAlive = (KeepAliveImpl as any) as {
|
||||
}
|
||||
}
|
||||
|
||||
function getName(comp: Component): string | void {
|
||||
function getName(comp: ConcreteComponent): string | void {
|
||||
return (comp as FunctionalComponent).displayName || comp.name
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ import { warn } from './warning'
|
||||
import { ComponentInternalInstance, Data } from './component'
|
||||
import { currentRenderingInstance } from './componentRenderUtils'
|
||||
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
|
||||
export interface DirectiveBinding<V = any> {
|
||||
instance: ComponentPublicInstance | null
|
||||
|
@ -68,11 +68,6 @@ interface Constructor<P = any> {
|
||||
new (): { $props: P }
|
||||
}
|
||||
|
||||
// Excludes Component type from returned `defineComponent`
|
||||
type NotDefinedComponent<T extends Component> = T extends Constructor
|
||||
? never
|
||||
: T
|
||||
|
||||
// The following is a series of overloads for providing props validation of
|
||||
// manually written render functions.
|
||||
|
||||
@ -117,9 +112,9 @@ export function h<P, E extends EmitsOptions = {}>(
|
||||
// catch-all for generic component types
|
||||
export function h(type: Component, children?: RawChildren): VNode
|
||||
|
||||
// exclude `defineComponent`
|
||||
export function h<Options extends ComponentOptions | FunctionalComponent<{}>>(
|
||||
type: NotDefinedComponent<Options>,
|
||||
// exclude `defineComponent` constructors
|
||||
export function h<T extends ComponentOptions | FunctionalComponent<{}>>(
|
||||
type: T,
|
||||
props?: RawProps | null,
|
||||
children?: RawChildren | RawSlots
|
||||
): VNode
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { currentRenderingInstance } from '../componentRenderUtils'
|
||||
import {
|
||||
currentInstance,
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
FunctionalComponent,
|
||||
ComponentOptions
|
||||
} from '../component'
|
||||
@ -16,7 +16,9 @@ const DIRECTIVES = 'directives'
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
export function resolveComponent(name: string): Component | string | undefined {
|
||||
export function resolveComponent(
|
||||
name: string
|
||||
): ConcreteComponent | string | undefined {
|
||||
return resolveAsset(COMPONENTS, name) || name
|
||||
}
|
||||
|
||||
@ -49,7 +51,7 @@ function resolveAsset(
|
||||
type: typeof COMPONENTS,
|
||||
name: string,
|
||||
warnMissing?: boolean
|
||||
): Component | undefined
|
||||
): ConcreteComponent | undefined
|
||||
// overload 2: directives
|
||||
function resolveAsset(
|
||||
type: typeof DIRECTIVES,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
import {
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
ComponentInternalInstance,
|
||||
ComponentOptions,
|
||||
InternalRenderFunction
|
||||
@ -10,7 +10,7 @@ import { extend } from '@vue/shared'
|
||||
|
||||
export let isHmrUpdating = false
|
||||
|
||||
export const hmrDirtyComponents = new Set<Component>()
|
||||
export const hmrDirtyComponents = new Set<ConcreteComponent>()
|
||||
|
||||
export interface HMRRuntime {
|
||||
createRecord: typeof createRecord
|
||||
|
@ -159,6 +159,7 @@ export {
|
||||
} from './vnode'
|
||||
export {
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
FunctionalComponent,
|
||||
ComponentInternalInstance,
|
||||
SetupContext,
|
||||
@ -178,7 +179,7 @@ export {
|
||||
export {
|
||||
ComponentPublicInstance,
|
||||
ComponentCustomProperties
|
||||
} from './componentProxy'
|
||||
} from './componentPublicInstance'
|
||||
export {
|
||||
Renderer,
|
||||
RendererNode,
|
||||
|
@ -66,7 +66,7 @@ import {
|
||||
import { createHydrationFunctions, RootHydrateFunction } from './hydration'
|
||||
import { invokeDirectiveHook } from './directives'
|
||||
import { startMeasure, endMeasure } from './profiling'
|
||||
import { ComponentPublicInstance } from './componentProxy'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
import { devtoolsComponentRemoved, devtoolsComponentUpdated } from './devtools'
|
||||
import { initFeatureFlags } from './featureFlags'
|
||||
|
||||
|
@ -15,8 +15,9 @@ import {
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
Data,
|
||||
Component,
|
||||
ClassComponent
|
||||
ConcreteComponent,
|
||||
ClassComponent,
|
||||
Component
|
||||
} from './component'
|
||||
import { RawSlots } from './componentSlots'
|
||||
import { isProxy, Ref, toRaw } from '@vue/reactivity'
|
||||
@ -244,7 +245,7 @@ export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
|
||||
if (
|
||||
__DEV__ &&
|
||||
n2.shapeFlag & ShapeFlags.COMPONENT &&
|
||||
hmrDirtyComponents.has(n2.type as Component)
|
||||
hmrDirtyComponents.has(n2.type as ConcreteComponent)
|
||||
) {
|
||||
// HMR only: if the component has been hot-updated, force a reload.
|
||||
return false
|
||||
|
@ -2,7 +2,7 @@ import { VNode } from './vnode'
|
||||
import {
|
||||
Data,
|
||||
ComponentInternalInstance,
|
||||
Component,
|
||||
ConcreteComponent,
|
||||
formatComponentName
|
||||
} from './component'
|
||||
import { isString, isFunction } from '@vue/shared'
|
||||
@ -10,7 +10,7 @@ import { toRaw, isRef, pauseTracking, resetTracking } from '@vue/reactivity'
|
||||
import { callWithErrorHandling, ErrorCodes } from './errorHandling'
|
||||
|
||||
type ComponentVNode = VNode & {
|
||||
type: Component
|
||||
type: ConcreteComponent
|
||||
}
|
||||
|
||||
const stack: VNode[] = []
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
describe,
|
||||
Component,
|
||||
defineComponent,
|
||||
PropType,
|
||||
ref,
|
||||
@ -179,6 +180,8 @@ describe('with object props', () => {
|
||||
}
|
||||
})
|
||||
|
||||
expectType<Component>(MyComponent)
|
||||
|
||||
// Test TSX
|
||||
expectType<JSX.Element>(
|
||||
<MyComponent
|
||||
@ -205,6 +208,17 @@ describe('with object props', () => {
|
||||
/>
|
||||
)
|
||||
|
||||
expectType<Component>(
|
||||
<MyComponent
|
||||
b="b"
|
||||
dd={{ n: 1 }}
|
||||
ddd={['ddd']}
|
||||
eee={() => ({ a: 'eee' })}
|
||||
fff={(a, b) => ({ a: a > +b })}
|
||||
hhh={false}
|
||||
/>
|
||||
)
|
||||
|
||||
// @ts-expect-error missing required props
|
||||
expectError(<MyComponent />)
|
||||
|
||||
|
@ -148,6 +148,7 @@ describe('h support for generic component type', () => {
|
||||
function foo(bar: Component) {
|
||||
h(bar)
|
||||
h(bar, 'hello')
|
||||
// @ts-expect-error
|
||||
h(bar, { id: 'ok' }, 'hello')
|
||||
}
|
||||
foo({})
|
||||
|
Loading…
Reference in New Issue
Block a user