Skip to content

Commit db15b9d

Browse files
committed
fix: stricter props types
At the moment, `mount()` offers [strong typing][1] of props, but this strong typing is lost when dealing with the `VueWrapper` through either the `props()` or `setProps()` methods. This change strengthens the typing of these methods to help raise compile-time errors when trying to get or set incorrect props. [1]: https://github.com/vuejs/test-utils/blob/11b34745e8e66fc747881dfb1ce94cef537c455e/src/types.ts#L44
1 parent 11b3474 commit db15b9d

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/vueWrapper.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,14 @@ export class VueWrapper<
215215
return this.componentVM
216216
}
217217

218-
props(): { [key: string]: any }
219-
props(selector: string): any
220-
props(selector?: string): { [key: string]: any } | any {
221-
const props = this.componentVM.$props as { [key: string]: any }
218+
props(): T['$props']
219+
props<Selector extends keyof T['$props']>(
220+
selector: Selector
221+
): T['$props'][Selector]
222+
props<Selector extends keyof T['$props']>(
223+
selector?: Selector
224+
): T['$props'] | T['$props'][Selector] {
225+
const props = this.componentVM.$props as T['$props']
222226
return selector ? props[selector] : props
223227
}
224228

@@ -240,7 +244,7 @@ export class VueWrapper<
240244
return nextTick()
241245
}
242246

243-
setProps(props: Record<string, unknown>): Promise<void> {
247+
setProps(props: T['$props']): Promise<void> {
244248
// if this VM's parent is not the root or if setProps does not exist, error out
245249
if (this.vm.$parent !== this.rootVM || !this.__setProps) {
246250
throw Error('You can only use setProps on your mounted component')

test-dts/wrapper.d-test.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,29 @@ expectType<boolean>(domWrapper.classes('class'))
116116

117117
// props
118118
expectType<{ [key: string]: any }>(wrapper.props())
119-
expectType<any>(wrapper.props('prop'))
119+
120+
const ComponentWithProps = defineComponent({
121+
props: {
122+
foo: String,
123+
bar: Number,
124+
},
125+
})
126+
127+
const propsWrapper = mount(ComponentWithProps);
128+
129+
propsWrapper.setProps({foo: 'abc'})
130+
propsWrapper.setProps({foo: 'abc', bar: 123})
131+
// @ts-expect-error :: should require string
132+
propsWrapper.setProps({foo: 123})
133+
// @ts-expect-error :: unknown prop
134+
propsWrapper.setProps({badProp: true})
135+
136+
expectType<string | undefined>(propsWrapper.props().foo)
137+
expectType<number | undefined>(propsWrapper.props().bar)
138+
// @ts-expect-error :: unknown prop
139+
propsWrapper.props().badProp;
140+
141+
expectType<string | undefined>(propsWrapper.props('foo'))
142+
expectType<number | undefined>(propsWrapper.props('bar'))
143+
// @ts-expect-error :: unknown prop
144+
propsWrapper.props('badProp')

0 commit comments

Comments
 (0)