= any,
>(
type: FunctionalComponent,
diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts
index 5d36407ba6a..478ae6bbb56 100644
--- a/packages/runtime-core/src/index.ts
+++ b/packages/runtime-core/src/index.ts
@@ -76,6 +76,7 @@ export {
withDefaults,
type DefineProps,
type ModelRef,
+ type ComponentTypeEmits,
} from './apiSetupHelpers'
/**
@@ -260,9 +261,6 @@ export type {
export type {
ComponentOptions,
ComponentOptionsMixin,
- ComponentOptionsWithoutProps,
- ComponentOptionsWithObjectProps,
- ComponentOptionsWithArrayProps,
ComponentCustomOptions,
ComponentOptionsBase,
ComponentProvideOptions,
@@ -272,7 +270,11 @@ export type {
RuntimeCompilerOptions,
ComponentInjectOptions,
} from './componentOptions'
-export type { EmitsOptions, ObjectEmitsOptions } from './componentEmits'
+export type {
+ ComponentEmitsOptions as EmitsOptions,
+ ObjectEmitsOptions,
+ EmitsToProps,
+} from './componentEmits'
export type {
ComponentPublicInstance,
ComponentCustomProperties,
diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts
index fb746f72c4a..cc56de2d685 100644
--- a/packages/runtime-dom/__tests__/customElement.spec.ts
+++ b/packages/runtime-dom/__tests__/customElement.spec.ts
@@ -88,10 +88,14 @@ describe('defineCustomElement', () => {
describe('props', () => {
const E = defineCustomElement({
- props: ['foo', 'bar', 'bazQux'],
+ props: {
+ foo: [String, null],
+ bar: Object,
+ bazQux: null,
+ },
render() {
return [
- h('div', null, this.foo),
+ h('div', null, this.foo || ''),
h('div', null, this.bazQux || (this.bar && this.bar.x)),
]
},
diff --git a/packages/runtime-dom/src/apiCustomElement.ts b/packages/runtime-dom/src/apiCustomElement.ts
index 01ce2bad464..b8adc761b37 100644
--- a/packages/runtime-dom/src/apiCustomElement.ts
+++ b/packages/runtime-dom/src/apiCustomElement.ts
@@ -1,16 +1,19 @@
import {
+ type Component,
+ type EmitsOptions as ComponentEmitsOptions,
type ComponentInjectOptions,
type ComponentInternalInstance,
+ type ComponentObjectPropsOptions,
type ComponentOptions,
+ type ComponentOptionsBase,
type ComponentOptionsMixin,
- type ComponentOptionsWithArrayProps,
- type ComponentOptionsWithObjectProps,
- type ComponentOptionsWithoutProps,
- type ComponentPropsOptions,
+ type ComponentProvideOptions,
type ComputedOptions,
type ConcreteComponent,
+ type CreateComponentPublicInstance,
type DefineComponent,
- type EmitsOptions,
+ type Directive,
+ type EmitsToProps,
type ExtractPropTypes,
type MethodOptions,
type RenderFunction,
@@ -41,98 +44,79 @@ export function defineCustomElement(
) => RawBindings | RenderFunction,
): VueElementConstructor
-// overload 2: object format with no props
+// overload 2: defineCustomElement with options object, infer props from options
export function defineCustomElement<
- Props = {},
- RawBindings = {},
- D = {},
- C extends ComputedOptions = {},
- M extends MethodOptions = {},
+ // props
+ PropsOptions extends
+ ComponentObjectPropsOptions = ComponentObjectPropsOptions,
+ PropsKeys extends string = string,
+ // emits
+ EmitsOptions extends ComponentEmitsOptions = {},
+ EmitsKeys extends string = string,
+ // other options
+ Data = {},
+ SetupBindings = {},
+ Computed extends ComputedOptions = {},
+ Methods extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
- E extends EmitsOptions = EmitsOptions,
- EE extends string = string,
- I extends ComponentInjectOptions = {},
- II extends string = string,
- S extends SlotsType = {},
+ InjectOptions extends ComponentInjectOptions = {},
+ InjectKeys extends string = string,
+ Slots extends SlotsType = {},
+ LocalComponents extends Record = {},
+ Directives extends Record = {},
+ Exposed extends string = string,
+ Provide extends ComponentProvideOptions = ComponentProvideOptions,
+ // resolved types
+ InferredProps = string extends PropsKeys
+ ? ComponentObjectPropsOptions extends PropsOptions
+ ? {}
+ : ExtractPropTypes
+ : { [key in PropsKeys]?: any },
+ ResolvedProps = InferredProps & EmitsToProps,
>(
- options: ComponentOptionsWithoutProps<
- Props,
- RawBindings,
- D,
- C,
- M,
+ options: {
+ props?: (PropsOptions & ThisType) | PropsKeys[]
+ } & ComponentOptionsBase<
+ ResolvedProps,
+ SetupBindings,
+ Data,
+ Computed,
+ Methods,
Mixin,
Extends,
- E,
- EE,
- I,
- II,
- S
- > & { styles?: string[] },
-): VueElementConstructor
-
-// overload 3: object format with array props declaration
-export function defineCustomElement<
- PropNames extends string,
- RawBindings,
- D,
- C extends ComputedOptions = {},
- M extends MethodOptions = {},
- Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
- Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
- E extends EmitsOptions = Record,
- EE extends string = string,
- I extends ComponentInjectOptions = {},
- II extends string = string,
- S extends SlotsType = {},
->(
- options: ComponentOptionsWithArrayProps<
- PropNames,
- RawBindings,
- D,
- C,
- M,
- Mixin,
- Extends,
- E,
- EE,
- I,
- II,
- S
- > & { styles?: string[] },
-): VueElementConstructor<{ [K in PropNames]: any }>
-
-// overload 4: object format with object props declaration
-export function defineCustomElement<
- PropsOptions extends Readonly,
- RawBindings,
- D,
- C extends ComputedOptions = {},
- M extends MethodOptions = {},
- Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
- Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
- E extends EmitsOptions = Record,
- EE extends string = string,
- I extends ComponentInjectOptions = {},
- II extends string = string,
- S extends SlotsType = {},
->(
- options: ComponentOptionsWithObjectProps<
- PropsOptions,
- RawBindings,
- D,
- C,
- M,
- Mixin,
- Extends,
- E,
- EE,
- I,
- II,
- S
- > & { styles?: string[] },
-): VueElementConstructor>
+ EmitsOptions,
+ EmitsKeys,
+ {}, // Defaults
+ InjectOptions,
+ InjectKeys,
+ Slots,
+ LocalComponents,
+ Directives,
+ Exposed,
+ Provide
+ > &
+ ThisType<
+ CreateComponentPublicInstance<
+ Readonly,
+ SetupBindings,
+ Data,
+ Computed,
+ Methods,
+ Mixin,
+ Extends,
+ EmitsOptions,
+ EmitsKeys,
+ {},
+ false,
+ InjectOptions,
+ Slots,
+ LocalComponents,
+ Directives,
+ Exposed
+ >
+ >,
+): VueElementConstructor
// overload 5: defining a custom element from the returned value of
// `defineComponent`