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

expect.subset() not type-safe #283

Open
dhardtke opened this issue May 17, 2023 · 1 comment
Open

expect.subset() not type-safe #283

dhardtke opened this issue May 17, 2023 · 1 comment

Comments

@dhardtke
Copy link
Contributor

dhardtke commented May 17, 2023

Hi,

first of all: Thanks a lot for all the work you have put into earl. We are currently evaluating if we will switch from chai to it because the lack of type-safety is really an issue.

We have tons of chai assertions using chai-subset that are written like this:

const items = [
  { _id: 42, foo: 'bar' },
  { _id: 43, foo: 'baz' },
  { _id: 44, lorem: 'ipsum' }
];

expect(items).to.containSubset([
  { _id: 42 },
  { _id: 44 }
])

The same assertion can be written with earl using:

expect(items).toInclude(
  expect.subset({ _id: 42 }),
  expect.subset({ _id: 44 }),
)

However it is not type safe as the following would also compile:

expect(items).toInclude(
  expect.subset({ x: 'y' }),
)

I would expect subset() to only accept Partials or (or deep Partials) of the type of items that are passed to expect().

@dhardtke dhardtke changed the title expect.toHaveSubset() not type-safe expect.subset() not type-safe May 17, 2023
@dhardtke
Copy link
Contributor Author

dhardtke commented Jun 9, 2023

Okay so I had a go at fixing this and pretty quickly stumbled upon that expect.subset, like all the other matchers, returns as type never. This is an issue since never can be assigned to any type.

So in my opinion either we change the types of all matchers (or add an optional generic of type T to Matcher) so that we can capture what was given to the matcher and reuse that inside the validators.

Based on toInclude my fix would then look like this:

interface Validators<T> {
  toInclude(
        this: Validators<T>,
        ...items: MemberOf<T>[]
      ): void
}

Or maybe it's a better approach to add a new Validator altogether for validating whether objects are (partially) included in a given array. Not sure about introducing bloat to the API though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant