Skip to content

Commit

Permalink
fix: accept FunctionalComponent<any> as selector
Browse files Browse the repository at this point in the history
Fixes #2594
  • Loading branch information
takejohn authored Jan 15, 2025
1 parent 38960da commit 0bb947f
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 32 deletions.
10 changes: 5 additions & 5 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1106,8 +1106,8 @@ Finds a Vue Component instance and returns a `VueWrapper` if found. Returns `Err
```ts
findComponent<T extends never>(selector: string): WrapperLike
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent>(selector: T | string): DOMWrapper<Element>
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent<any>>(selector: T | string): DOMWrapper<Element>
findComponent<T extends never>(selector: NameSelector | RefSelector): VueWrapper
findComponent<T extends ComponentPublicInstance>(selector: T | FindComponentSelector): VueWrapper<T>
findComponent(selector: FindComponentSelector): WrapperLike
Expand Down Expand Up @@ -1224,9 +1224,9 @@ wrapper.findComponent<DefineComponent>('.foo') // returns VueWrapper
```ts
findAllComponents<T extends never>(selector: string): WrapperLike[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends never>(selector: NameSelector): VueWrapper[]
findAllComponents<T extends ComponentPublicInstance>(selector: T | FindAllComponentsSelector): VueWrapper<T>[]
findAllComponents(selector: FindAllComponentsSelector): WrapperLike[]
Expand Down
10 changes: 5 additions & 5 deletions docs/fr/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1101,8 +1101,8 @@ Trouve une instance de composant Vue et renvoie un `VueWrapper` si trouvé. Renv

```ts
findComponent<T extends never>(selector: string): WrapperLike
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent>(selector: T | string): DOMWrapper<Element>
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent<any>>(selector: T | string): DOMWrapper<Element>
findComponent<T extends never>(selector: NameSelector | RefSelector): VueWrapper
findComponent<T extends ComponentPublicInstance>(selector: T | FindComponentSelector): VueWrapper<T>
findComponent(selector: FindComponentSelector): WrapperLike
Expand Down Expand Up @@ -1218,9 +1218,9 @@ wrapper.findComponent<DefineComponent>('.foo'); // retourne VueWrapper

```ts
findAllComponents<T extends never>(selector: string): WrapperLike[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends never>(selector: NameSelector): VueWrapper[]
findAllComponents<T extends ComponentPublicInstance>(selector: T | FindAllComponentsSelector): VueWrapper<T>[]
findAllComponents(selector: FindAllComponentsSelector): WrapperLike[]
Expand Down
10 changes: 5 additions & 5 deletions docs/zh/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1104,8 +1104,8 @@ test('findAll', () => {

```ts
findComponent<T extends never>(selector: string): WrapperLike
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent>(selector: T | string): DOMWrapper<Element>
findComponent<T extends DefinedComponent>(selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent<any>>(selector: T | string): DOMWrapper<Element>
findComponent<T extends never>(selector: NameSelector | RefSelector): VueWrapper
findComponent<T extends ComponentPublicInstance>(selector: T | FindComponentSelector): VueWrapper<T>
findComponent(selector: FindComponentSelector): WrapperLike
Expand Down Expand Up @@ -1222,9 +1222,9 @@ wrapper.findComponent<DefineComponent>('.foo') // returns VueWrapper

```ts
findAllComponents<T extends never>(selector: string): WrapperLike[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends DefinedComponent>(selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent<any>>): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: string): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent<any>>(selector: T): DOMWrapper<Node>[]
findAllComponents<T extends never>(selector: NameSelector): VueWrapper[]
findAllComponents<T extends ComponentPublicInstance>(selector: T | FindAllComponentsSelector): VueWrapper<T>[]
findAllComponents(selector: FindAllComponentsSelector): WrapperLike[]
Expand Down
18 changes: 10 additions & 8 deletions src/baseWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ export default abstract class BaseWrapper<ElementType extends Node>
>
// searching for component created via defineComponent results in VueWrapper of proper type
findComponent<T extends DefinedComponent>(
selector: T | Exclude<FindComponentSelector, FunctionalComponent>
selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>
): VueWrapper<InstanceType<T>>
// searching for functional component results in DOMWrapper
findComponent<T extends FunctionalComponent>(selector: T): DOMWrapper<Node>
findComponent<T extends FunctionalComponent>(
findComponent<T extends FunctionalComponent<any>>(
selector: T
): DOMWrapper<Node>
findComponent<T extends FunctionalComponent<any>>(
selector: string
): DOMWrapper<Element>
// searching by name or ref always results in VueWrapper
Expand Down Expand Up @@ -189,12 +191,12 @@ export default abstract class BaseWrapper<ElementType extends Node>

findAllComponents<T extends never>(selector: string): WrapperLike[]
findAllComponents<T extends DefinedComponent>(
selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent>
selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent<any>>
): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent>(
findAllComponents<T extends FunctionalComponent<any>>(
selector: T
): DOMWrapper<Node>[]
findAllComponents<T extends FunctionalComponent>(
findAllComponents<T extends FunctionalComponent<any>>(
selector: string
): DOMWrapper<Element>[]
findAllComponents<T extends never>(selector: NameSelector): VueWrapper[]
Expand Down Expand Up @@ -296,10 +298,10 @@ export default abstract class BaseWrapper<ElementType extends Node>

getComponent<T extends never>(selector: string): Omit<WrapperLike, 'exists'>
getComponent<T extends DefinedComponent>(
selector: T | Exclude<FindComponentSelector, FunctionalComponent>
selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>
): Omit<VueWrapper<InstanceType<T>>, 'exists'>
// searching for functional component results in DOMWrapper
getComponent<T extends FunctionalComponent>(
getComponent<T extends FunctionalComponent<any>>(
selector: T | string
): Omit<DOMWrapper<Element>, 'exists'>
// searching by name or ref always results in VueWrapper
Expand Down
14 changes: 7 additions & 7 deletions src/interfaces/wrapperLike.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export default interface WrapperLike {

findComponent<T extends never>(selector: string): WrapperLike
findComponent<T extends DefinedComponent>(
selector: T | Exclude<FindComponentSelector, FunctionalComponent>
selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>
): VueWrapper<InstanceType<T>>
findComponent<T extends FunctionalComponent>(
findComponent<T extends FunctionalComponent<any>>(
selector: T | string
): DOMWrapper<Element>
findComponent<T extends never>(
Expand All @@ -49,12 +49,12 @@ export default interface WrapperLike {

findAllComponents<T extends never>(selector: string): WrapperLike[]
findAllComponents<T extends DefinedComponent>(
selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent>
selector: T | Exclude<FindAllComponentsSelector, FunctionalComponent<any>>
): VueWrapper<InstanceType<T>>[]
findAllComponents<T extends FunctionalComponent>(
findAllComponents<T extends FunctionalComponent<any>>(
selector: string
): DOMWrapper<Element>[]
findAllComponents<T extends FunctionalComponent>(
findAllComponents<T extends FunctionalComponent<any>>(
selector: T
): DOMWrapper<Node>[]
findAllComponents<T extends never>(selector: NameSelector): VueWrapper[]
Expand All @@ -78,10 +78,10 @@ export default interface WrapperLike {

getComponent<T extends never>(selector: string): Omit<WrapperLike, 'exists'>
getComponent<T extends DefinedComponent>(
selector: T | Exclude<FindComponentSelector, FunctionalComponent>
selector: T | Exclude<FindComponentSelector, FunctionalComponent<any>>
): Omit<VueWrapper<InstanceType<T>>, 'exists'>
// searching for functional component results in DOMWrapper
getComponent<T extends FunctionalComponent>(
getComponent<T extends FunctionalComponent<any>>(
selector: T | string
): Omit<DOMWrapper<Element>, 'exists'>
getComponent<T extends ComponentPublicInstance>(
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface NameSelector {

export type FindAllComponentsSelector =
| DefinedComponent
| FunctionalComponent
| FunctionalComponent<any>
| ComponentOptions
| NameSelector
| string
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export function isComponent(

export function isFunctionalComponent(
component: unknown
): component is FunctionalComponent {
): component is FunctionalComponent<any> {
return typeof component === 'function' && !isClassComponent(component)
}

Expand Down
27 changes: 27 additions & 0 deletions test-dts/findComponent.d-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import WrapperLike from '../src/interfaces/wrapperLike'

const FuncComponent = () => 'hello'

const FuncComponentWithProps = (props: { a: string }) => 'hello'

const FuncComponentWithEmits = (
props: object,
ctx: { emit: (event: 'hi') => void }
) => 'hello'

const ComponentToFind = defineComponent({
props: {
a: {
Expand Down Expand Up @@ -43,6 +50,18 @@ expectType<VueWrapper<InstanceType<typeof ComponentWithEmits>>>(
const functionalComponentByType = wrapper.findComponent(FuncComponent)
expectType<DOMWrapper<Node>>(functionalComponentByType)

// find by type - functional component with props
const functionalComponentWithPropsByType = wrapper.findComponent(
FuncComponentWithProps
)
expectType<DOMWrapper<Node>>(functionalComponentWithPropsByType)

// find by type - functional component with emits
const functionalComponentWithEmitsByType = wrapper.findComponent(
FuncComponentWithEmits
)
expectType<DOMWrapper<Node>>(functionalComponentWithEmitsByType)

// find by string
const componentByString = wrapper.findComponent('.foo')
expectType<WrapperLike>(componentByString)
Expand All @@ -58,6 +77,14 @@ const functionalComponentByStringWithParam =
wrapper.findComponent<typeof FuncComponent>('.foo')
expectType<DOMWrapper<Element>>(functionalComponentByStringWithParam)

const functionalComponentWithPropsByString =
wrapper.findComponent<typeof FuncComponentWithProps>('.foo')
expectType<DOMWrapper<Element>>(functionalComponentWithPropsByString)

const functionalComponentWithEmitsByString =
wrapper.findComponent<typeof FuncComponentWithEmits>('.foo')
expectType<DOMWrapper<Element>>(functionalComponentWithEmitsByString)

// find by ref
const componentByRef = wrapper.findComponent({ ref: 'foo' })
expectType<VueWrapper>(componentByRef)
Expand Down

0 comments on commit 0bb947f

Please sign in to comment.