Skip to content
Vitest 1
Main Navigation РуководствоAPIКонфигурацияПродвинутый
1.6.1
0.34.6

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Внешний вид

Sidebar Navigation

Руководство

Зачем Vitest

Начало работы

Функциональность

Рабочая область

Интерфейс командной строки

Фильтрация тестов

Репортёры

Покрытие кода

Снапшоты

Мокирование

Тестирование типов

Vitest UI

Режим браузера

In-source тестирование (Тестирование в исходном коде)

Контекст теста

Тестовая среда

Расширение проверок (matchers)

Интеграции с IDE

Отладка

Сравнения с другими тестовыми фреймворками

Руководство по миграции

Распространенные ошибки

Улучшение производительности

API

Справочник по Test API

Mock-функции

Vitest

expect

expectTypeOf

assert

assertType

Конфигурация

Настройка конфигурационного файла Vitest

Настройка Vitest

Содержание страницы

Тестирование типов ​

Пример проекта

GitHub - Play Online

Vitest позволяет писать тесты для ваших типов, используя синтаксис expectTypeOf или assertType. По умолчанию, все файлы *.test-d.ts считаются файлами с тестами типов, но это можно изменить с помощью опции конфигурации typecheck.include.

Под капотом Vitest вызывает tsc или vue-tsc, в зависимости от вашей конфигурации, и анализирует результаты. Vitest также отображает ошибки типов в вашем исходном коде, если они обнаружены. Это поведение можно отключить с помощью опции конфигурации typecheck.ignoreSourceErrors.

Важно понимать, что Vitest не запускает и не компилирует эти файлы. Они лишь статически анализируются компилятором. Следовательно, использование динамических операторов невозможно. Это означает, что динамические имена тестов и API test.each, test.runIf, test.skipIf, test.concurrent не поддерживаются. Однако, другие API, такие как test, describe, .only, .skip и .todo, можно использовать.

Использование флагов CLI, таких как --allowOnly и -t, также поддерживается для проверки типов.

ts
import { assertType, expectTypeOf } from 'vitest';
import { mount } from './mount.js';

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction();
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }));
});

Любая ошибка типов, обнаруженная в тестовом файле, будет рассматриваться как ошибка теста. Это позволяет использовать любые продвинутые техники работы с типами для тестирования типов вашего проекта.

Список доступных матчеров можно найти в разделе API.

Интерпретация ошибок ​

При использовании API expectTypeOf, обратитесь к документации expect-type о сообщениях об ошибках.

Когда типы не совпадают, .toEqualTypeOf и .toMatchTypeOf используют специальный вспомогательный тип для генерации максимально информативных сообщений об ошибках. Однако, их интерпретация имеет некоторые особенности. Поскольку утверждения строятся последовательно, ошибка должна быть указана для "ожидаемого" типа, а не для "фактического" типа (expect<Actual>().toEqualTypeOf<Expected>()). Это означает, что сообщения об ошибках типов могут быть несколько запутанными. Для решения этой проблемы библиотека создает тип MismatchInfo, чтобы максимально четко указать, что ожидается. Например:

ts
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();

Это утверждение завершится ошибкой, поскольку {a: 1} имеет тип {a: number}, а не {a: string}. В этом случае сообщение об ошибке будет выглядеть примерно так:

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}>()

Обратите внимание, что в сообщении об ограничении типа четко указаны как "ожидаемый", так и "фактический" типы. Вместо того, чтобы воспринимать фразу Types of property 'a' are incompatible // Type 'string' is not assignable to type "Expected: string, Actual: number" буквально, обратите внимание на имя свойства ('a') и сообщение: Expected: string, Actual: number. Это подскажет вам, в чем проблема, в большинстве случаев. Чрезвычайно сложные типы, конечно, потребуют больше времени на отладку и могут потребовать некоторой экспериментальной работы. Пожалуйста, создайте issue, если сообщения об ошибках действительно вводят в заблуждение.

Методы toBe... (например, toBeString, toBeNumber, toBeVoid и т. д.) завершаются ошибкой, если Actual тип не соответствует ожидаемому, приводя к невызываемому типу. Например, ошибка для утверждения, подобного expectTypeOf(1).toBeString(), будет выглядеть примерно так:

test/test.ts:999:999 - error TS2349: This expression is not callable.
  Type 'ExpectString<number>' has no call signatures.

999 expectTypeOf(1).toBeString()
                    ~~~~~~~~~~

Фраза This expression is not callable не очень информативна. Более полезная информация об ошибке находится в следующей строке: Type 'ExpectString<number> has no call signatures. Это, по сути, означает, что вы передали число, но утверждали, что это должна быть строка.

Если бы TypeScript добавил поддержку для "throw" types, эти сообщения об ошибках можно было бы значительно улучшить. До тех пор для их интерпретации потребуется определенное усилие.

Конкретные объекты и аргументы типов ​

Сообщения об ошибках для утверждения, подобного этому:

ts
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: '' });

Будут менее полезными, чем для утверждения, подобного этому:

ts
expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>();

Это связано с тем, что компилятору TypeScript необходимо вывести аргумент типа (typearg) для .toEqualTypeOf({a: ''}), и библиотека может определить несоответствие, только сравнив его с универсальным типом Mismatch. Поэтому, где это возможно, используйте аргумент типа, а не конкретный тип для .toEqualTypeOf и toMatchTypeOf. Если удобнее сравнивать два конкретных типа, можно использовать typeof:

ts
const one = valueFromFunctionOne({ some: { complex: inputs } });
const two = valueFromFunctionTwo({ some: { other: inputs } });

expectTypeOf(one).toEqualTypeof<typeof two>();

Если у вас возникают сложности с API expectTypeOf и пониманием ошибок, вы всегда можете использовать более простой API assertType:

ts
const answer = 42;

assertType<number>(answer);
// @ts-expect-error answer is not a string
assertType<string>(answer);

TIP

При использовании синтаксиса @ts-expect-error рекомендуется убедиться в отсутствии опечаток. Вы можете сделать это, включив файлы типов в опцию конфигурации test.include, чтобы Vitest также фактически запускал эти тесты и завершался с ошибкой ReferenceError.

Это пройдет, потому что ожидает ошибку, но в слове «answer» есть опечатка, поэтому это ложноположительная ошибка:

ts
// @ts-expect-error answer is not a string
assertType<string>(answr); //

Запуск проверки типов ​

Начиная с Vitest 1.0, чтобы включить проверку типов, добавьте флаг --typecheck в команду Vitest в файле package.json:

json
{
  "scripts": {
    "test": "vitest --typecheck"
  }
}

Теперь вы можете запустить проверку типов:

bash
npm run test
bash
yarn test
bash
pnpm run test
bash
bun test

Vitest использует tsc --noEmit или vue-tsc --noEmit, в зависимости от вашей конфигурации, поэтому эти скрипты можно удалить из процесса сборки.

Pager
Предыдущая страницаМокирование
Следующая страницаVitest UI

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors

https://v1.vitest.dev/guide/testing-types

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors