diff --git a/src/mount.ts b/src/mount.ts index 0878f9c1f..ca570dcc1 100644 --- a/src/mount.ts +++ b/src/mount.ts @@ -21,7 +21,8 @@ import { ComputedOptions, ComponentPropsOptions, ComponentOptions, - ConcreteComponent + ConcreteComponent, + Prop } from 'vue' import { MountingOptions, Slot } from './types' @@ -73,6 +74,25 @@ function getInstanceOptions( return resultOptions } +// Class component (without vue-class-component) - no props +export function mount( + originalComponent: { + new (...args: any[]): V + __vccOpts: any + }, + options?: MountingOptions & Record +): VueWrapper> + +// Class component (without vue-class-component) - props +export function mount( + originalComponent: { + new (...args: any[]): V + __vccOpts: any + defaultProps?: Record> | string[] + }, + options?: MountingOptions

& Record +): VueWrapper> + // Class component - no props export function mount( originalComponent: { diff --git a/test-dts/mount.d-test.ts b/test-dts/mount.d-test.ts index 2119437c8..b753fafc4 100644 --- a/test-dts/mount.d-test.ts +++ b/test-dts/mount.d-test.ts @@ -1,8 +1,15 @@ import { expectError, expectType } from './index' import { + ComponentOptions, DefineComponent, defineComponent, - FunctionalComponent + FunctionalComponent, + getCurrentInstance, + h, + ref, + SetupContext, + Prop, + VNodeChild } from 'vue' import { Options, Vue } from 'vue-class-component' import { mount } from '../src' @@ -179,7 +186,7 @@ declare const FunctionalComponentEmit: FunctionalComponent< level: number }, { hello: (foo: string, bar: string) => void } -> + > mount(FunctionalComponent) mount(defineComponent(FunctionalComponent)) @@ -211,6 +218,78 @@ class ClassComponent extends Vue { expectError(mount(ClassComponent, {}).vm.changeMessage()) mount(ClassComponent, {}).vm.changeMessage('') +// region custom class component implement +class CustomClassComponent { + static defaultProps?: Record> | string[] + private static __vccValue?: ComponentOptions + static get __vccOpts(): ComponentOptions { + if (this.__vccValue) return this.__vccValue + const CompConstructor = this + return (this.__vccValue = { + name: CompConstructor.name, + props: CompConstructor.defaultProps, + setup(props, ctx) { + const instance = new CompConstructor() + return instance.render.bind(instance) + } + }) + } + constructor() { + const instance = getCurrentInstance()! + this.props = instance.props as Props + // @ts-expect-error no explicit setupContext on instance + this.context = instance.setupContext as SetupContext + } + + props: Props + get $props() { + return this.props + } + context: SetupContext + render(): VNodeChild {} +} +class NoPropCustomClassComponent extends CustomClassComponent { + count = ref(0) + changeCount(count: number) { + this.count.value = count + } + render() { + return h('div', `hello world ${this.count.value}`) + } +} + +// @ts-expect-error changeCount expects an argument +expectError(mount(NoPropCustomClassComponent, {}).vm.changeCount()) +mount(NoPropCustomClassComponent, {}).vm.changeCount(2) + +interface CustomClassComponentProps { + size: 'small' | 'large' + age?: number +} + +class WithPropCustomClassComponent extends CustomClassComponent { + static defaultProps: (keyof CustomClassComponentProps)[] = ['size', 'age'] + count = ref(0) + changeCount(count: number) { + this.count.value = count + } + render() { + return h('div', `hello world ${this.count.value}${this.props.size}`) + } +} + +expectError( + // @ts-expect-error should has props error + mount(WithPropCustomClassComponent, { + props: {} + }) +) +mount(WithPropCustomClassComponent, { + props: { size: 'small' } +}) + +// endregion + // default props const Foo = defineComponent({ props: {