From b3badd30ca3b494000aa8b51d8f733ea7bc86fb8 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 Aug 2025 22:44:27 +0200 Subject: [PATCH] docs: update Testing Types docs to use non-deprecated expect-type API and add toMatchObjectType documentation (#8397) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sheremet-va <16173870+sheremet-va@users.noreply.github.com> --- api/expect-typeof.md | 41 +++++++++++++++++++++++++++++++++++++++++ guide/features.md | 2 +- guide/testing-types.md | 6 +++--- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/api/expect-typeof.md b/api/expect-typeof.md index d3fce9ce..c94785df 100644 --- a/api/expect-typeof.md +++ b/api/expect-typeof.md @@ -31,6 +31,9 @@ expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>() - **Type:** `(expected: T) => void` +::: warning DEPRECATED +This matcher has been deprecated since expect-type v1.2.0. Use [`toExtend`](#toextend) instead. +::: This matcher checks if expect type extends provided type. It is different from `toEqual` and is more similar to [expect's](/api/expect) `toMatchObject()`. With this matcher, you can check if an object “matches” a type. ```ts @@ -41,6 +44,44 @@ expectTypeOf().toMatchTypeOf() expectTypeOf().not.toMatchTypeOf() ``` +## toExtend + +- **Type:** `(expected: T) => void` + +This matcher checks if expect type extends provided type. It is different from `toEqual` and is more similar to [expect's](/api/expect) `toMatchObject()`. With this matcher, you can check if an object "matches" a type. + +```ts +import { expectTypeOf } from 'vitest' + +expectTypeOf({ a: 1, b: 1 }).toExtend({ a: 1 }) +expectTypeOf().toExtend() +expectTypeOf().not.toExtend() +``` + +## toMatchObjectType + +- **Type:** `() => void` + +This matcher performs a strict check on object types, ensuring that the expected type matches the provided object type. It's stricter than [`toExtend`](#toextend) and is the recommended choice when working with object types as it's more likely to catch issues like readonly properties. + +```ts +import { expectTypeOf } from 'vitest' + +expectTypeOf({ a: 1, b: 2 }).toMatchObjectType<{ a: number }>() // preferred +expectTypeOf({ a: 1, b: 2 }).toExtend<{ a: number }>() // works but less strict + +// Supports nested object checking +const user = { + name: 'John', + address: { city: 'New York', zip: '10001' } +} +expectTypeOf(user).toMatchObjectType<{ name: string; address: { city: string } }>() +``` + +::: warning +This matcher only works with plain object types. It will fail for union types and other complex types. For those cases, use [`toExtend`](#toextend) instead. +::: + ## extract - **Type:** `ExpectTypeOf` diff --git a/guide/features.md b/guide/features.md index add249ef..f1aeb892 100644 --- a/guide/features.md +++ b/guide/features.md @@ -224,7 +224,7 @@ import { mount } from './mount.js' test('my types work properly', () => { expectTypeOf(mount).toBeFunction() - expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>() + expectTypeOf(mount).parameter(0).toExtend<{ name: string }>() // @ts-expect-error name is a string assertType(mount({ name: 42 })) diff --git a/guide/testing-types.md b/guide/testing-types.md index d16efb10..d6933de4 100644 --- a/guide/testing-types.md +++ b/guide/testing-types.md @@ -30,7 +30,7 @@ import { mount } from './mount.js' test('my types work properly', () => { expectTypeOf(mount).toBeFunction() - expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>() + expectTypeOf(mount).parameter(0).toExtend<{ name: string }>() // @ts-expect-error name is a string assertType(mount({ name: 42 })) @@ -45,7 +45,7 @@ You can see a list of possible matchers in [API section](/api/expect-typeof). If you are using `expectTypeOf` API, refer to the [expect-type documentation on its error messages](https://github.com/mmkal/expect-type#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: +When types don't match, `.toEqualTypeOf` and `.toExtend` 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 }>() @@ -91,7 +91,7 @@ Will be less helpful than for an assertion like this: 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`: +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 `.toExtend`. If it's much more convenient to compare two concrete types, you can use `typeof`: ```ts const one = valueFromFunctionOne({ some: { complex: inputs } })