Type definitions of > v3.2.1 using any type
aukevanleeuwen opened this issue · 0 comments
Bug
package
version:3.2.3
node
version:16.x
npm
(oryarn
) version: yarn1.22.19
What you did:
What happened (please provide anything you think will help):
I want to use the ESLint rule @typescript-eslint/no-unsafe-assignment
, even in my test code if at all possible. With v3.2.3
(basically v3.2.2+
I think) this gives lots of errors like this:
/some/path/to/some/typescript/test/file/booking-entity.it.ts
209:70 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
265:17 error Unsafe assignment of an `any` value @typescript-eslint/no-unsafe-assignment
Relevant code:
expect(updatedBooking).toEqual({ ...expectedBooking, updatedAt: expect.toBeDateString() });
There are two ways (that I know of) to use a Jest matcher:
-
expect(something).toBeDateString()
-
expect(something).toEqual({ // other props createdAt: expect.toBeDateString() });
This second case gives the linting warnings obviously. I guess the typing is quite difficult to get right, because it seems the return type depends on the context of how it's used. I doubt we can type that properly. However, it seems to be that the first case (1) is pretty much always void
. If would do const foo = expect(something).toBeDateString();
, foo
would be undefined. In the other case: I don't know of any usage within Jest where you could do: expect.toBeDateString().andThenSomeChainedMethodOrProperty()
. Is there?
If not: wouldn't the pragmatic way of typing this matchers not be (in this case): string
?
I can imagine that, since this is technically not correct, people would object to this, but I don't like any
either. Maybe we can settle for unknown
instead? I think that would at least make my linter happy.
N.B. more verbose stuff below.
The reason why string
would be nice is that if you have the following:
interface Foo {
// other properties
createdAt: string;
}
// with following test (structure) - doing this by heart
const actual = sut.somethingThatReturnsAFoo();
// ↓↓↓
const expected: Foo = {
// other properties
createdAt: expect.toBeDateString(), // ← TypeScript will complain here
}
expect(actual).toEqual(expected);
Typescript will complain because expect.toBeDateString()
is not of type string
, but it is quite nice sometimes to have your expected
typed, so that you don't make any typos in other properties for example. I understand that I should do
const expected: Foo = {
// other properties
createdAt: expect.toBeDateString() as string,
}
in that case, because in fact it is some kind of (asymmetric?) matcher or something special that Jest knows what to do with. Just saying that if somebody would come up with that matcher type it would probably be even worse, because the as string
will then need another cast since that matcher type and string will not have any overlap. So then it would be as unknown as string
😬 . Again, I would mostly favor the pragmatic approach of saying: from a usage perspective this is essentially a string
(for this specific matcher, obviously it differs per extended matcher).