Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type safe assertions #5702

Open
4 tasks done
krzkaczor opened this issue May 10, 2024 · 3 comments
Open
4 tasks done

Type safe assertions #5702

krzkaczor opened this issue May 10, 2024 · 3 comments
Labels
enhancement: pending triage p2-to-be-discussed Enhancement under consideration (priority)

Comments

@krzkaczor
Copy link

krzkaczor commented May 10, 2024

Clear and concise description of the problem

Right now it's possible to construct assertions (let's say using expect api) that will always fail because they compare values of different types, yet there are not type errors.

Consider this:

expect(123).toBe('123')

This is obviously a mistake that will fail in runtime but will pass happily in compile time.

Having type safe assertions becomes very handy during refactorings when compiler can guide the developer through all required changes. Consider slightly more complex example:

const returnValue = functionCall()
expect(returnValue).toEqual({ a: 1, b: 2 })

Once functionCall return type changes in the future, TypeScript type checker would point the developer to all assertions that need to be updated. Right now this has to be done by executing tests which results in worse DX.

In bun test runner same code will result in a type error in a compile time, clearly visible to developer.

image

Suggested solution

I propose making assertions api type safe. This can be done by parameterizing matchers by a type represented by actual value. Most likely due to various edge cases in comparison of complex TS objects that would be a breaking change.

Alternative

No response

Additional context

In the past I created earl which takes this idea to extreme: https://github.com/l2beat/earl#example

Validations

@AriPerkkio
Copy link
Member

Is this essentially same as #2883?

@krzkaczor
Copy link
Author

#2883 is a little bit different because it's about type narrowing ie. changing a type of a variable after a given statement, in this example ensuring that something is truthy. From my experience with earl this is really hard with expect style API, on the other hand, having type-safe assertions is doable.

In the original issue I mention only toBe and toEqual cases but you can imagine this working for all different matchers.

expect(false).toBeTruthy(); // type error because false is can never be truthy

@AriPerkkio
Copy link
Member

While this could definitely be nice in some cases, it could also make tests hard to work on. Discussion from earlier mentioned Bun: oven-sh/bun#6934

This could likely be solved by third party package that overwrites the typings to more strict ones. Making the built-in default ones strict would break Jest compatibility as well.

@AriPerkkio AriPerkkio added the p2-to-be-discussed Enhancement under consideration (priority) label May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement: pending triage p2-to-be-discussed Enhancement under consideration (priority)
Projects
Status: P2 - 3
Development

No branches or pull requests

2 participants