Skip to content

Suggesting R = unknown for custom matchers makes asymmetric matchers error #7731

@kettanaito

Description

@kettanaito

Describe the bug

Here's how Vitest docs recommend declaring types for custom matchers.

interface CustomMatchers<R = unknown> {
  toBeFoo: () => R
}

While this works with symmetric matchers (expect(a).toBeFoo()), when you apply this to an asymmetric one, the unknown return type of the matcher will result in a type error.

interface O {
  s: string
}

expect({ s: 'foo' }).toEqual<O>({ s: expect.toBeFoo() })
Type 'unknown' is not assignable to type '{ s string; }'.ts(2322)

Suggested solutions

  1. Consider defaulting to any instead of unknown. The two are not the same and are not interchangeable[1]. Here, it looks like any may be a better fit.

In fact, I think it should've been any from the start. The matcher itself cannot infer or guarantee a type of the value (that'd be out of its scope). The best it can do is be anything.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-2narajwa?file=vite.config.ts,test%2Fbasic.test.ts&initialPath=__vitest__/

Go to test/basic.test.ts and see the type error when asserting on the s property. It must not be there.

System Info

Irrelevant.

Used Package Manager

npm

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions