У меня есть проект машинописного текста, в котором есть несколько модульных тестов, использующих расширения сопоставителей из vitest. Тест проходит нормально, но если я запускаю lint, я продолжаю получать такие ошибки:
src/utils/tests/dateFilterUtils.test.ts:75:9 — ошибка TS2339: свойство toHaveMessage не существует для типа Assertion<DateInputErrorI, Any>.
Это файл, в котором у меня есть customMatcher
export const addCustomMatchers = (): void => {
expect.extend({
/**
* Accepts an object with a message property and passes if the message is a non-empty string.
*/
toHaveMessage(received: { message: string }) {
return {
pass: typeof received?.message === 'string' && received?.message?.length > 0,
message: () =>
this.utils.matcherHint('toHaveMessage', undefined, '', {
isNot: this.isNot,
} as any) +
'\n\n' +
`Received: ${this.utils.printReceived(received)}`,
};
},
});
};
Я добавил файл vitest.d.ts, который упоминается в документации и который выглядит вот так
interface CustomMatchers<R = unknown> {
toHaveMessage: () => R;
}
declare module 'vitest' {
type Assertion<T = any> = CustomMatchers<T>;
interface AsymmetricMatchersContaining extends CustomMatchers {}
}
Я также дал ссылку на vitest.d.ts в разделе файлов моего файла tsconfig.json.
Как я уже упоминал ранее, модульные тесты работают нормально, но при выполнении компилятора машинописного текста возникает ошибка.
Обновлено: Вот код dateFilterUtils.test.ts
import { addHours, startOfToday, subHours } from 'date-fns';
import { useDateInputFields, validateDateInputFields } from '../dateFilterUtils';
import { describe, test, expect } from 'vitest';
const getMockDateInputFieldsValue = (date: Date): ReturnType<typeof useDateInputFields> => {
return {
fullDate: date,
year: date.getFullYear().toString(),
month: (date.getMonth() + 1).toString(),
day: date.getDate().toString(),
time: `${date.getHours().toString()}:${date.getMinutes().toString()}`,
} as ReturnType<typeof useDateInputFields>;
};
describe('dateFilterUtils', () => {
describe('validateDateInputFields', () => {
// Mock date input fields values for use in tests
const empty = {
fullDate: null,
year: '',
month: '',
day: '',
time: '',
} as ReturnType<typeof useDateInputFields>;
const future = getMockDateInputFieldsValue(new Date(2999, 2, 21, 12));
const today = getMockDateInputFieldsValue(addHours(startOfToday(), 2)); // Note: assumes tests will not be run between 00:00 and 02:00
const yesterday = getMockDateInputFieldsValue(subHours(startOfToday(), 2));
const past = getMockDateInputFieldsValue(new Date(2007, 2, 21, 12));
test('returns error if date is not valid', () => {
expect(validateDateInputFields(empty)).not.toHaveMessage();
expect(validateDateInputFields(past)).not.toHaveMessage();
expect(validateDateInputFields({ ...past, fullDate: null })).toHaveMessage();
});
test('returns error if date should be before the start of the current day', () => {
expect(validateDateInputFields(future)).not.toHaveMessage();
expect(validateDateInputFields(future, { mustBeBeforeStartOfToday: true })).toHaveMessage();
expect(validateDateInputFields(today, { mustBeBeforeStartOfToday: true })).toHaveMessage();
expect(
validateDateInputFields(yesterday, { mustBeBeforeStartOfToday: true })
).not.toHaveMessage();
expect(validateDateInputFields(past, { mustBeBeforeStartOfToday: true })).not.toHaveMessage();
});
test('returns error if date should be after the start of the current day', () => {
expect(validateDateInputFields(yesterday)).not.toHaveMessage();
expect(validateDateInputFields(future, { mustBeTodayOrInFuture: true })).not.toHaveMessage();
expect(validateDateInputFields(today, { mustBeTodayOrInFuture: true })).not.toHaveMessage();
expect(validateDateInputFields(yesterday, { mustBeTodayOrInFuture: true })).toHaveMessage();
expect(validateDateInputFields(past, { mustBeTodayOrInFuture: true })).toHaveMessage();
});
test('returns error if date should be in the future', () => {
expect(validateDateInputFields(past)).not.toHaveMessage();
expect(validateDateInputFields(future, { mustBeInFuture: true })).not.toHaveMessage();
expect(validateDateInputFields(today, { mustBeInFuture: true })).toHaveMessage();
expect(validateDateInputFields(yesterday, { mustBeInFuture: true })).toHaveMessage();
expect(validateDateInputFields(past, { mustBeInFuture: true })).toHaveMessage();
});
test('returns error if date should be equal or after start date', () => {
expect(
validateDateInputFields(past, { mustBeAfterDate: new Date(1900, 0) })
).not.toHaveMessage();
expect(validateDateInputFields(past, { mustBeAfterDate: new Date(2999, 0) })).toHaveMessage();
});
test('returns error if date should be after start date', () => {
expect(
validateDateInputFields(past, { mustBeEqualOrAfterDate: new Date(2007, 2, 21, 12) })
).not.toHaveMessage();
expect(
validateDateInputFields(past, { mustBeEqualOrAfterDate: new Date(2999, 0) })
).toHaveMessage();
});
test('returns error if time is not optional and time empty', () => {
const date = getMockDateInputFieldsValue(new Date(2999, 2, 21));
date.time = '';
expect(validateDateInputFields(date, { isTimeOptional: true })).not.toHaveMessage();
expect(validateDateInputFields(date, { isTimeOptional: false })).toHaveMessage();
});
});
});
Спасибо, я обновил вопрос, включив в него этот файл.
В файле vitest.d.ts вы определяете свойство toBeNullOrUndefined
, но ваш CustomMatcher
определяет toHaveMessage
.
Так что измените его на
interface CustomMatchers<R = unknown> {
toHaveMessage: () => R;
}
Извините, это была опечатка при попытке уменьшить файл, включив в него только одно из средств сопоставления расширений, которые я использовал. Я изменил это на toHaveMessage и все еще получаю ту же ошибку.
Похоже, что я использовал это, поскольку мой vitest.d.ts сработал: import { Assertion } from 'vitest'; объявить модуль 'vitest' {экспортировать интерфейс Assertion { toHaveMessage(expectedMessage?: string): Assertion; } }
Использование этого в vitest.d.ts решило проблему.
import { Assertion } from 'vitest';
declare module 'vitest' {
export interface Assertion {
toHaveMessage(expectedMessage?: string): Assertion;
}
}
Это не ошибка ESLint — она исходит от компилятора Typescript. Идентифицируется по префиксу «TS». Итак, проблема в «src/utils/tests/dateFilterUtils.test.ts»; которым вы не поделились в своем вопросе.