Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/vitest/src/node/config/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { getWorkersCountByPercentage } from '../../utils/workers'
import { BaseSequencer } from '../sequencers/BaseSequencer'
import { RandomSequencer } from '../sequencers/RandomSequencer'

const loggedExperimentalWarnings = new WeakSet<Logger>()

function resolvePath(path: string, root: string) {
// local-pkg (mlly)'s resolveModule("./file", { paths: ["/some/root"] }) tries
// /some/file
Expand Down Expand Up @@ -796,7 +798,8 @@ export function resolveConfig(
resolved.typecheck ??= {} as any
resolved.typecheck.enabled ??= false

if (resolved.typecheck.enabled) {
if (resolved.typecheck.enabled && !loggedExperimentalWarnings.has(logger)) {
loggedExperimentalWarnings.add(logger)
logger.console.warn(
Copy link
Copy Markdown
Member

@sheremet-va sheremet-va Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should define logger.warnOnce like vite does. And maybe we should use it for all experimental warning

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm definitely not against that, and id prefer that as well was just trying to keep the pr small and to scope since it's first contribution. But I'll go ahead and work on doing it that's way it's probably cleaner.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got real sick I'll look at this again this weekend

c.yellow(
'Testing types with tsc and vue-tsc is an experimental feature.\nBreaking changes might not follow SemVer, please pin Vitest\'s version when using it.',
Expand Down
18 changes: 18 additions & 0 deletions test/typescript/test/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,24 @@ it('throws an error if typechecker process exists', async () => {
}
})

it('logs experimental typecheck warning once for a run with multiple typecheck projects', async () => {
// Each project with typecheck.enabled triggers a separate resolveConfig call.
// Without dedup, PROJECT_COUNT warnings would be logged. Assert exactly one.
const PROJECT_COUNT = 5
const { stderr } = await runVitest({
root: resolve(import.meta.dirname, '..'),
projects: Array.from({ length: PROJECT_COUNT }, (_, i) => ({
test: {
name: `typecheck-project-${i + 1}`,
dir: resolve(import.meta.dirname, '../test-d'),
typecheck: { enabled: true },
},
})),
})
const warningCount = (stderr.match(/Testing types with tsc and vue-tsc is an experimental feature/g) ?? []).length
expect(warningCount).toBe(1)
})

function removeLines(log: string) {
return log.replace(/⎯{2,}/g, '⎯⎯')
}
Loading