Skip to content

Commit

Permalink
fix: stricter props types
Browse files Browse the repository at this point in the history
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
  • Loading branch information
alecgibson committed Jul 25, 2023
1 parent 11b3474 commit db15b9d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
14 changes: 9 additions & 5 deletions src/vueWrapper.ts
Expand Up @@ -215,10 +215,14 @@ export class VueWrapper<
return this.componentVM
}

props(): { [key: string]: any }
props(selector: string): any
props(selector?: string): { [key: string]: any } | any {
const props = this.componentVM.$props as { [key: string]: any }
props(): T['$props']
props<Selector extends keyof T['$props']>(
selector: Selector
): T['$props'][Selector]
props<Selector extends keyof T['$props']>(
selector?: Selector
): T['$props'] | T['$props'][Selector] {
const props = this.componentVM.$props as T['$props']
return selector ? props[selector] : props
}

Expand All @@ -240,7 +244,7 @@ export class VueWrapper<
return nextTick()
}

setProps(props: Record<string, unknown>): Promise<void> {
setProps(props: T['$props']): Promise<void> {
// if this VM's parent is not the root or if setProps does not exist, error out
if (this.vm.$parent !== this.rootVM || !this.__setProps) {
throw Error('You can only use setProps on your mounted component')
Expand Down
27 changes: 26 additions & 1 deletion test-dts/wrapper.d-test.ts
Expand Up @@ -116,4 +116,29 @@ expectType<boolean>(domWrapper.classes('class'))

// props
expectType<{ [key: string]: any }>(wrapper.props())
expectType<any>(wrapper.props('prop'))

const ComponentWithProps = defineComponent({
props: {
foo: String,
bar: Number,
},
})

const propsWrapper = mount(ComponentWithProps);

propsWrapper.setProps({foo: 'abc'})
propsWrapper.setProps({foo: 'abc', bar: 123})
// @ts-expect-error :: should require string
propsWrapper.setProps({foo: 123})
// @ts-expect-error :: unknown prop
propsWrapper.setProps({badProp: true})

expectType<string | undefined>(propsWrapper.props().foo)
expectType<number | undefined>(propsWrapper.props().bar)
// @ts-expect-error :: unknown prop
propsWrapper.props().badProp;

expectType<string | undefined>(propsWrapper.props('foo'))
expectType<number | undefined>(propsWrapper.props('bar'))
// @ts-expect-error :: unknown prop
propsWrapper.props('badProp')

0 comments on commit db15b9d

Please sign in to comment.