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

Expose "toExtend" functions #36

Closed
JacobLey opened this issue Sep 10, 2023 · 2 comments · Fixed by #16
Closed

Expose "toExtend" functions #36

JacobLey opened this issue Sep 10, 2023 · 2 comments · Fixed by #16

Comments

@JacobLey
Copy link

Alongside the existing ExpectTypeOf methods, a method to check for successful extension of types would be helpful. Perhaps a strict/branded version as well.

Proposed syntax:

expectTypeOf<5>().toExtend<number>();
expectTypeOf<unknown>().toExtend<any>();
expectTypeOf('abc').toExtend([{}]); // Typescript error

expectTypeOf<5>().toStrictExtend<number>();
expectTypeOf<unknown>().toStrictExtend<any>(); // Typescript error
expectTypeOf('abc').toStrictExtend([{}]); // Typescript error

I would be happy to submit a PR for this. Especially since the Extends and StrictExtends types are already implemented, just not directly exposed in the main method.

My current workaround is:

expectTypeOf<
     StrictExtends<Foo, Bar>
>().toBeEqual<true>();

Admittedly the grammar is a bit different (most methods start with toBe) so open to a renaming to match. toBeExtending...?

@JacobLey
Copy link
Author

Ah I think I was confused reading through code.

Looks like this is effectively toMatchTypeOf, which is always the non-strict type.

I guess the followup is instead to support the strict "branded" version of toMatchTypeOf (similar to branded.toEqualTypeOf)

@mmkal
Copy link
Owner

mmkal commented Sep 30, 2023

This is toMatchTypeOf, but I am considering deprecating toMatchTypeOf in favour of something like toExtend (probably making toMatchTypeOf an alias). Similarly I might rename toEqualTypeOf to be some kind of toBeIdenticalTo. But, for now, use toMatchTypeOf. I'll leave this open until that happens (or I decide definitively not to do that).

@mmkal mmkal mentioned this issue Oct 1, 2023
2 tasks
mmkal added a commit that referenced this issue Oct 1, 2023
re: #37 and #36
@mmkal mmkal closed this as completed in #16 Oct 3, 2023
mmkal added a commit that referenced this issue Oct 3, 2023
Fixes #17
Closes #36 (by documenting that `toMatchTypeOf` ~= `toExtend`)
Closes #37 (by documenting that helper types are not part of the API
surface)
Closes #32
Closes #4
Closes #6 (by documenting that you _can't_ use
`.not.toBeCallableWith(...)`)
Closes #38

Use generics to give better error messages than "Arguments for the rest
parameter 'MISMATCH' were not provided" for most `toEqualTypeOf` cases
and many `toMatchTypeOf` cases. This trades off some implementation
complexity for better end-user error messages. Essentially, write a
special `<Expected extends ...>` constraint for each overload of each
method, which does some crazy conditional logic, which boil down to:

- `<Expected extends Actual>` for `toEqualTypeOf` (when we aren't in a
`.not` context)
- `<Expected extends Satisfies<Actual>>` for `toMatchTypeOf`

Anyone interested, have a look at the snapshot updates in
`errors.test.ts.snap` to see what the real world difference is.

Each of these constraints apply only when we know it's going to "fail" -
i.e. `Satisfies<...>` is a fairly meaningless helper type that is used
to try to show errors at the type-constraint level rather than the
`...MISMATCH: MismatchArgs<...>` level which won't give good error
messages.

When using `.not`, the constraint just becomes `extends unknown`, and
you'll have to squint as before.

See also: #14 for the better long-term solution, _if_ the TypeScript
team decide to merge the throw types PR.
See also: #13 for a hopefully-complementary improvement to the
information on hover, which will improve the cases this doesn't cover.

TODO:

- [x] See if the `expectTypeOf({a: 1}).toMatchTypeOf({a: 'one'})` case
can also be improved.
- [x] Document. The constraints are a bit different to what most users
would be used to, so it's worth highlighting the best way to read error
messages and clarify when they might default to "Arguments for the rest
parameter 'MISMATCH' were not provided"

Note: I have publish v0.17.0-1 based on this PR and will hopefully be
able to use [that version in
vitest](vitest-dev/vitest#4206) as a test before
merging.
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

Successfully merging a pull request may close this issue.

2 participants