Skip to content

Commit 8f0d12a

Browse files
committed
fix: vm should be properly typed
The types have been tweaked to avoid the need of casting like `(wrapper.vm as any).msg`.
1 parent 62aca6d commit 8f0d12a

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

src/mount.ts

+16-5
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import {
88
Plugin,
99
Directive,
1010
Component,
11-
reactive
11+
reactive,
12+
ComponentPublicInstance
1213
} from 'vue'
1314

14-
import { createWrapper } from './vue-wrapper'
15+
import { createWrapper, VueWrapper } from './vue-wrapper'
1516
import { createEmitMixin } from './emitMixin'
1617
import { createDataMixin } from './dataMixin'
1718
import { MOUNT_ELEMENT_ID } from './constants'
@@ -37,7 +38,14 @@ interface MountingOptions {
3738
stubs?: Record<string, any>
3839
}
3940

40-
export function mount(originalComponent: any, options?: MountingOptions) {
41+
export function mount<T extends any>(
42+
originalComponent: any,
43+
options?: MountingOptions
44+
): VueWrapper<any>
45+
export function mount<T extends ComponentPublicInstance>(
46+
originalComponent: new () => T,
47+
options?: MountingOptions
48+
): VueWrapper<T> {
4149
const component = { ...originalComponent }
4250

4351
// Reset the document.body
@@ -63,7 +71,10 @@ export function mount(originalComponent: any, options?: MountingOptions) {
6371
// override component data with mounting options data
6472
if (options?.data) {
6573
const dataMixin = createDataMixin(options.data())
66-
component.mixins = [...(component.mixins || []), dataMixin]
74+
;(component as any).mixins = [
75+
...((component as any).mixins || []),
76+
dataMixin
77+
]
6778
}
6879

6980
// we define props as reactive so that way when we update them with `setProps`
@@ -136,5 +147,5 @@ export function mount(originalComponent: any, options?: MountingOptions) {
136147
// mount the app!
137148
const app = vm.mount(el)
138149

139-
return createWrapper(app, events, setProps)
150+
return createWrapper<T>(app, events, setProps)
140151
}

src/vue-wrapper.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import { WrapperAPI } from './types'
66
import { ErrorWrapper } from './error-wrapper'
77
import { MOUNT_ELEMENT_ID } from './constants'
88

9-
export class VueWrapper implements WrapperAPI {
10-
private componentVM: ComponentPublicInstance
9+
export class VueWrapper<T extends ComponentPublicInstance>
10+
implements WrapperAPI {
11+
private componentVM: T
1112
private __emitted: Record<string, unknown[]> = {}
1213
private __vm: ComponentPublicInstance
1314
private __setProps: (props: Record<string, any>) => void
@@ -19,9 +20,7 @@ export class VueWrapper implements WrapperAPI {
1920
) {
2021
this.__vm = vm
2122
this.__setProps = setProps
22-
this.componentVM = this.__vm.$refs[
23-
'VTU_COMPONENT'
24-
] as ComponentPublicInstance
23+
this.componentVM = this.__vm.$refs['VTU_COMPONENT'] as T
2524
this.__emitted = events
2625
}
2726

@@ -43,7 +42,7 @@ export class VueWrapper implements WrapperAPI {
4342
return this.hasMultipleRoots ? this.parentElement : this.componentVM.$el
4443
}
4544

46-
get vm(): ComponentPublicInstance {
45+
get vm(): T {
4746
return this.componentVM
4847
}
4948

@@ -106,10 +105,10 @@ export class VueWrapper implements WrapperAPI {
106105
}
107106
}
108107

109-
export function createWrapper(
108+
export function createWrapper<T extends ComponentPublicInstance>(
110109
vm: ComponentPublicInstance,
111110
events: Record<string, unknown[]>,
112111
setProps: (props: Record<string, any>) => void
113-
): VueWrapper {
114-
return new VueWrapper(vm, events, setProps)
112+
): VueWrapper<T> {
113+
return new VueWrapper<T>(vm, events, setProps)
115114
}

tests/vm.spec.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ describe('vm', () => {
99
setup() {
1010
const msg = 'hello'
1111
const isEnabled = ref(true)
12-
return { msg, isEnabled }
12+
const toggle = () => (isEnabled.value = !isEnabled.value)
13+
return { msg, isEnabled, toggle }
1314
}
1415
})
1516

1617
const wrapper = mount(Component)
1718

18-
expect((wrapper.vm as any).msg).toBe('hello')
19-
expect((wrapper.vm as any).isEnabled).toBe(true)
19+
expect(wrapper.vm.msg).toBe('hello')
20+
expect(wrapper.vm.isEnabled).toBe(true)
21+
22+
wrapper.vm.toggle()
23+
24+
expect(wrapper.vm.isEnabled).toBe(false)
2025
})
2126
})

0 commit comments

Comments
 (0)