mmkal/expect-type (expect-type)
### [`v0.17.3`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.3)
[Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.17.2...v0.17.3)
- docs: why-is-my-assertion-failing [`907b8aa`](https://togithub.com/mmkal/expect-type/commit/907b8aa)
- I think the previous build was out of date somehow too, so see https://github.com/mmkal/expect-type/releases/v0.17.2
### [`v0.17.2`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.2)
[Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.17.1...v0.17.2)
- Improve tuple errors ([#40](https://togithub.com/mmkal/expect-type/issues/40)) [`4b38117`](https://togithub.com/mmkal/expect-type/commit/4b38117)
Diff(truncated - scroll right!):
```diff
test('toEqualTypeOf with tuples', () => {
const assertion = `expectTypeOf<[[number], [1], []]>().toEqualTypeOf<[[number], [2], []]>()`
expect(tsErrors(assertion)).toMatchInlineSnapshot(`
- "test/test.ts:999:999 - error TS2344: Type '[[number], [2], []]' does not satisfy the constraint '{ [x: number]: { [x: number]: number; [iterator]: (() => IterableIterator<1>) | (() => IterableIterator) | (() => IterableIterator); [unscopables]: (() => { copyWithin: boolean; entries: boolean; fill: boolean; find: boolean; findIndex: boolean; keys: boolean; values: boolean; }) | (() => { copyWithin: boolean; entries: boolean; fill: boolean; find: boolean; findIndex: boolean; keys: boolean; values: boolean; }) | (() => { copyWithin: boolean; entries: boolean; fill: boolean; find: boolean; findIndex: boolean; keys: boolean; values: boolean; }); length: 0 | 1; toString: ... truncated!!!!'.
- Types of property 'sort' are incompatible.
- Type '(compareFn?: ((a: [] | [number] | [2], b: [] | [number] | [2]) => number) | undefined) => [[number], [2], []]' is not assignable to type '\\"Expected: function, Actual: function\\"'.
+ "test/test.ts:999:999 - error TS2344: Type '[[number], [2], []]' does not satisfy the constraint '{ 0: { 0: number; }; 1: { 0: \\"Expected: literal number: 2, Actual: literal number: 1\\"; }; 2: {}; }'.
+ The types of '1[0]' are incompatible between these types.
+ Type '2' is not assignable to type '\\"Expected: literal number: 2, Actual: literal number: 1\\"'.
999 expectTypeOf<[[number], [1], []]>().toEqualTypeOf<[[number], [2], []]>()
~~~~~~~~~~~~~~~~~~~"
`)
})
```
### [`v0.17.1`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.1)
[Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.17.0...v0.17.1)
- disallow `.not` and `.branded` together [`cf38918`](https://togithub.com/mmkal/expect-type/commit/cf38918)
(this was actually documented in the [v0.17.0 release](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.0) but really it was only pushed here)
### [`v0.17.0`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.0)
[Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.16.0...v0.17.0)
[#16](https://togithub.com/mmkal/expect-type/issues/16) went in to - hopefully - significantly improve the error messages produce on failing assertions. Here's an example of how vitest's failing tests were improved:
Before:
After:
Docs copied from [the readme](https://togithub.com/mmkal/expect-type#error-messages) about how to interpret these error messages
***
##### Error messages
When types don't match, `.toEqualTypeOf` and `.toMatchTypeOf` use a special helper type to produce error messages that are as actionable as possible. But there's a bit of an nuance to understanding them. Since the assertions are written "fluently", the failure should be on the "expected" type, not the "actual" type (`expect().toEqualTypeOf()`). This means that type errors can be a little confusing - so this library produces a `MismatchInfo` type to try to make explicit what the expectation is. For example:
```ts
expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>()
```
Is an assertion that will fail, since `{a: 1}` has type `{a: number}` and not `{a: string}`. The error message in this case will read something like this:
test/test.ts:999:999 - error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: \\"Expected: string, Actual: number\\"; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type '\\"Expected: string, Actual: number\\"'.
999 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>()
Note that the type constraint reported is a human-readable messaging specifying both the "expected" and "actual" types. Rather than taking the sentence `Types of property 'a' are incompatible // Type 'string' is not assignable to type "Expected: string, Actual: number"` literally - just look at the property name (`'a'`) and the message: `Expected: string, Actual: number`. This will tell you what's wrong, in most cases. Extremely complex types will of course be more effort to debug, and may require some experimentation. Please [raise an issue](https://togithub.com/mmkal/expect-type) if the error messages are actually misleading.
The `toBe...` methods (like `toBeString`, `toBeNumber`, `toBeVoid` etc.) fail by resolving to a non-callable type when the `Actual` type under test doesn't match up. For example, the failure for an assertion like `expectTypeOf(1).toBeString()` will look something like this:
test/test.ts:999:999 - error TS2349: This expression is not callable.
Type 'ExpectString' has no call signatures.
999 expectTypeOf(1).toBeString()
~~~~~~~~~~
The `This expression is not callable` part isn't all that helpful - the meaningful error is the next line, `Type 'ExpectString has no call signatures`. This essentially means you passed a number but asserted it should be a string.
If TypeScript added support for ["throw" types](https://togithub.com/microsoft/TypeScript/pull/40468) these error messagess could be improved. Until then they will take a certain amount of squinting.
##### Concrete "expected" objects vs typeargs
Error messages for an assertion like this:
```ts
expectTypeOf({a: 1}).toEqualTypeOf({a: ''})
```
Will be less helpful than for an assertion like this:
```ts
expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>()
```
This is because the TypeScript compiler needs to infer the typearg for the `.toEqualTypeOf({a: ''})` style, and this library can only mark it as a failure by comparing it against a generic `Mismatch` type. So, where possible, use a typearg rather than a concrete type for `.toEqualTypeOf` and `toMatchTypeOf`. If it's much more convenient to compare two concrete types, you can use `typeof`:
```ts
const one = valueFromFunctionOne({some: {complex: inputs}})
const two = valueFromFunctionTwo({some: {other: inputs}})
expectTypeOf(one).toEqualTypeof()
```
***
Kinda-breaking changes: essentially none, but technically, `.branded` no longer returns a "full" `ExpectTypeOf` instance at compile-time. Previously you could do this:
```ts
expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.not.toEqualTypeOf<{a: {b: 1; c: ''}}>()
expectTypeOf<{a: {b: 1} & {c: 1}}>().not.branded.toEqualTypeOf<{a: {b: 1; c: ''}}>()
```
Now that won't work (and it was always slightly nonsensical), so you'd have to use `// @ts-expect-error` instead of `not` if you have a negated case where you need `branded`:
```ts
// @ts-expect-error
expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.not.toEqualTypeOf<{a: {b: 1; c: ''}}>()
```
***
#### What's Changed
- Improve CLI error messages by [@mmkal](https://togithub.com/mmkal) in [https://github.com/mmkal/expect-type/pull/16](https://togithub.com/mmkal/expect-type/pull/16)
- expect-type is usually a dev dependency by [@SerkanSipahi](https://togithub.com/SerkanSipahi) in [https://github.com/mmkal/expect-type/pull/39](https://togithub.com/mmkal/expect-type/pull/39)
#### New Contributors
- [@SerkanSipahi](https://togithub.com/SerkanSipahi) made their first contribution in [https://github.com/mmkal/expect-type/pull/39](https://togithub.com/mmkal/expect-type/pull/39)
**Full Changelog**: https://github.com/mmkal/expect-type/compare/v0.16.0...v0.17.0
Configuration
š Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
š¦ Automerge: Enabled.
ā» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
š Ignore: Close this PR and you won't be reminded about this update again.
[ ] If you want to rebase/retry this PR, check this box
This PR has been generated by Mend Renovate. View repository job log here.
This PR contains the following updates:
0.16.0
->0.17.3
Release Notes
mmkal/expect-type (expect-type)
### [`v0.17.3`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.3) [Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.17.2...v0.17.3) - docs: why-is-my-assertion-failing [`907b8aa`](https://togithub.com/mmkal/expect-type/commit/907b8aa) - I think the previous build was out of date somehow too, so see https://github.com/mmkal/expect-type/releases/v0.17.2 ### [`v0.17.2`](https://togithub.com/mmkal/expect-type/releases/tag/v0.17.2) [Compare Source](https://togithub.com/mmkal/expect-type/compare/v0.17.1...v0.17.2) - Improve tuple errors ([#40](https://togithub.com/mmkal/expect-type/issues/40)) [`4b38117`](https://togithub.com/mmkal/expect-type/commit/4b38117) Diff(truncated - scroll right!): ```diff test('toEqualTypeOf with tuples', () => { const assertion = `expectTypeOf<[[number], [1], []]>().toEqualTypeOf<[[number], [2], []]>()` expect(tsErrors(assertion)).toMatchInlineSnapshot(` - "test/test.ts:999:999 - error TS2344: Type '[[number], [2], []]' does not satisfy the constraint '{ [x: number]: { [x: number]: number; [iterator]: (() => IterableIterator<1>) | (() => IterableIteratorConfiguration
š Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
š¦ Automerge: Enabled.
ā» Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
š Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate. View repository job log here.