Skip to content

Commit 2e0e1a6

Browse files
committed
some improvements and added missing types on VueWrapper
1 parent 6cabf7f commit 2e0e1a6

File tree

3 files changed

+98
-50
lines changed

3 files changed

+98
-50
lines changed

src/mount.ts

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { ComponentPublicInstance, DefineComponent, VNode } from 'vue'
2-
import type {
3-
ComponentExposed,
1+
import {
2+
ComponentPublicInstance,
3+
DefineComponent,
4+
VNode,
45
ComponentProps,
5-
ComponentSlots
6-
} from 'vue-component-type-helpers'
6+
ComponentInstance
7+
} from 'vue'
8+
import type { ComponentSlots } from 'vue-component-type-helpers'
79
import { createInstance } from './createInstance'
810
import { MountingOptions } from './types'
911
import { trackInstance } from './utils/autoUnmount'
@@ -18,10 +20,10 @@ type WithArray<T> = T | T[]
1820

1921
type ComponentData<T> = T extends { data?(...args: any): infer D } ? D : {}
2022

21-
export type ComponentMountingOptions<
22-
T,
23-
P extends ComponentProps<T> = ComponentProps<T>
24-
> = Omit<MountingOptions<P, ComponentData<T>>, 'slots'> & {
23+
export type ComponentMountingOptions<T, P> = Omit<
24+
MountingOptions<P, ComponentData<T>>,
25+
'slots'
26+
> & {
2527
slots?: {
2628
[K in keyof ComponentSlots<T>]: WithArray<
2729
| ShimSlotReturnType<ComponentSlots<T>[K]>
@@ -33,28 +35,25 @@ export type ComponentMountingOptions<
3335
}
3436
} & Record<string, unknown>
3537

38+
// defineComponent
3639
export function mount<
37-
T,
38-
C = T extends ((...args: any) => any) | (new (...args: any) => any)
39-
? T
40-
: T extends { props?: infer Props }
41-
? DefineComponent<
42-
Props extends Readonly<(infer PropNames)[]> | (infer PropNames)[]
43-
? { [key in PropNames extends string ? PropNames : string]?: any }
44-
: Props
45-
>
46-
: DefineComponent,
47-
P extends ComponentProps<C> = ComponentProps<C>
40+
T extends DefineComponent<
41+
PropsOrOptions,
42+
any,
43+
any,
44+
any,
45+
any,
46+
any,
47+
any,
48+
any,
49+
any,
50+
any
51+
>,
52+
PropsOrOptions
4853
>(
4954
originalComponent: T,
50-
options?: ComponentMountingOptions<C, P>
51-
): VueWrapper<
52-
ComponentProps<C> & ComponentData<C> & ComponentExposed<C>,
53-
ComponentPublicInstance<
54-
ComponentProps<C>,
55-
ComponentData<C> & ComponentExposed<C> & Omit<P, keyof ComponentProps<C>>
56-
>
57-
>
55+
options?: ComponentMountingOptions<T, ComponentProps<T>>
56+
): VueWrapper<ComponentInstance<T>>
5857

5958
// implementation
6059
export function mount(

src/renderToString.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,44 @@
11
import { renderToString as baseRenderToString } from '@vue/server-renderer'
2-
import { DefineComponent } from 'vue'
2+
import { ComponentProps, DefineComponent } from 'vue'
33
import { createInstance } from './createInstance'
44
import { ComponentMountingOptions } from './mount'
55
import { RenderMountingOptions } from './types'
66

7+
// export function renderToString<
8+
// T,
9+
// C = T extends ((...args: any) => any) | (new (...args: any) => any)
10+
// ? T
11+
// : T extends { props?: infer Props }
12+
// ? DefineComponent<
13+
// Props extends Readonly<(infer PropNames)[]> | (infer PropNames)[]
14+
// ? { [key in PropNames extends string ? PropNames : string]?: any }
15+
// : Props
16+
// >
17+
// : DefineComponent
18+
// >(
19+
// originalComponent: T,
20+
// options?: ComponentMountingOptions<C> &
21+
// Pick<RenderMountingOptions<any>, 'attachTo'>
22+
// ): Promise<string>
23+
24+
// defineComponent
725
export function renderToString<
8-
T,
9-
C = T extends ((...args: any) => any) | (new (...args: any) => any)
10-
? T
11-
: T extends { props?: infer Props }
12-
? DefineComponent<
13-
Props extends Readonly<(infer PropNames)[]> | (infer PropNames)[]
14-
? { [key in PropNames extends string ? PropNames : string]?: any }
15-
: Props
16-
>
17-
: DefineComponent
26+
T extends DefineComponent<
27+
PropsOrOptions,
28+
any,
29+
any,
30+
any,
31+
any,
32+
any,
33+
any,
34+
any,
35+
any,
36+
any
37+
>,
38+
PropsOrOptions
1839
>(
1940
originalComponent: T,
20-
options?: ComponentMountingOptions<C> &
41+
options?: ComponentMountingOptions<T, ComponentProps<T>> &
2142
Pick<RenderMountingOptions<any>, 'attachTo'>
2243
): Promise<string>
2344

src/vueWrapper.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { nextTick, App, ComponentPublicInstance, VNode } from 'vue'
1+
import {
2+
nextTick,
3+
App,
4+
ComponentPublicInstance,
5+
VNode,
6+
ExtractComponentEmits
7+
} from 'vue'
28

39
import { config } from './config'
410
import domEvents from './constants/dom-events'
@@ -72,9 +78,24 @@ function createVMProxy<T extends ComponentPublicInstance>(
7278
})
7379
}
7480

81+
type ResolveComponentEmitKeys<T> = keyof ResolveEmitRecord<T>
82+
83+
type ResolveEmitRecord<T> = ExtractComponentEmits<T> extends infer E
84+
? [E] extends [Array<infer EE extends string>]
85+
? Record<EE, any[]>
86+
: {
87+
[K in keyof E]: (E[K] extends (...args: infer Args) => any
88+
? Args extends { length: 0 }
89+
? void
90+
: Args extends { length: 1 }
91+
? Args[0]
92+
: Args
93+
: void)[]
94+
}
95+
: never
96+
7597
export class VueWrapper<
76-
VM = unknown,
77-
T extends ComponentPublicInstance = VM & ComponentPublicInstance
98+
T extends ComponentPublicInstance = ComponentPublicInstance
7899
> extends BaseWrapper<Node> {
79100
private readonly componentVM: T
80101
private readonly rootVM: ComponentPublicInstance | undefined | null
@@ -226,11 +247,11 @@ export class VueWrapper<
226247
return selector ? props[selector] : props
227248
}
228249

229-
emitted<T = unknown>(): Record<string, T[]>
230-
emitted<T = unknown[]>(eventName: string): undefined | T[]
231-
emitted<T = unknown>(
232-
eventName?: string
233-
): undefined | T[] | Record<string, T[]> {
250+
emitted(): ResolveEmitRecord<T>
251+
emitted<E extends ResolveComponentEmitKeys<T>>(
252+
eventName: E
253+
): undefined | ResolveEmitRecord<T>[E]
254+
emitted(eventName?: string) {
234255
return emitted(this.vm, eventName)
235256
}
236257

@@ -239,7 +260,7 @@ export class VueWrapper<
239260
return domWrapper.isVisible()
240261
}
241262

242-
setData(data: Record<string, unknown>): Promise<void> {
263+
setData(data: Partial<T['$data']>): Promise<void> {
243264
mergeDeep(this.componentVM.$data, data)
244265
return nextTick()
245266
}
@@ -253,7 +274,14 @@ export class VueWrapper<
253274
return nextTick()
254275
}
255276

256-
setValue(value: unknown, prop?: string): Promise<void> {
277+
setValue<
278+
V extends T['$props'] extends { modelValue?: infer MV } ? MV : never
279+
>(value: V): Promise<void>
280+
setValue<P extends keyof T['$props']>(
281+
value: T['$props'][P],
282+
prop: P
283+
): Promise<void>
284+
setValue(value: unknown, prop?: unknown): Promise<void> {
257285
const propEvent = prop || 'modelValue'
258286
this.vm.$emit(`update:${propEvent}`, value)
259287
return this.vm.$nextTick()

0 commit comments

Comments
 (0)