From 414de13bd886769645415144856bdcff30b46c52 Mon Sep 17 00:00:00 2001 From: Yevhenii Date: Thu, 26 Feb 2026 14:14:39 +0200 Subject: [PATCH] fix(types): remove extends ImportMeta from ModuleRunnerImportMeta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove `extends ImportMeta` to prevent TS2717 "subsequent property declarations must have the same type" in consumer projects using skipLibCheck: false with augmented ImportMeta - Add explicit fields (dirname, filename, resolve, glob, main) that were previously inherited, so consumers get real types instead of falling through the `[key: string]: any` index signature - Add `main: false` to createDefaultImportMeta (previously only set in createNodeImportMeta) - Remove `satisfies Omit as any` — the function return type annotation handles the check, and with explicit fields the Omit workaround is no longer needed - Add type test verifying ModuleRunnerImportMeta is assignable to ImportMeta (including @types/node augmentations) — catches future inconsistencies without causing declaration-level conflicts --- packages/vite/package.json | 2 +- .../module-runner/__tests_dts__/importMeta.ts | 20 +++++++++++++++++++ .../module-runner/__tests_dts__/tsconfig.json | 9 +++++++++ .../src/module-runner/createImportMeta.ts | 4 ++-- packages/vite/src/module-runner/types.ts | 7 ++++++- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 packages/vite/src/module-runner/__tests_dts__/importMeta.ts create mode 100644 packages/vite/src/module-runner/__tests_dts__/tsconfig.json diff --git a/packages/vite/package.json b/packages/vite/package.json index 07a92c5e5776da..b785c1a9ff1a9a 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -65,7 +65,7 @@ "build-types": "pnpm build-types-roll && pnpm build-types-check", "build-types-roll": "rolldown --config rolldown.dts.config.ts", "build-types-check": "tsc --project tsconfig.check.json", - "typecheck": "tsc && tsc -p src/node && tsc -p src/module-runner && tsc -p src/shared && tsc -p src/node/__tests_dts__", + "typecheck": "tsc && tsc -p src/node && tsc -p src/module-runner && tsc -p src/shared && tsc -p src/node/__tests_dts__ && tsc -p src/module-runner/__tests_dts__", "lint": "eslint --cache --ext .ts src/**", "format": "prettier --write --cache --parser typescript \"src/**/*.ts\"", "generate-target": "tsx scripts/generateTarget.ts", diff --git a/packages/vite/src/module-runner/__tests_dts__/importMeta.ts b/packages/vite/src/module-runner/__tests_dts__/importMeta.ts new file mode 100644 index 00000000000000..d447e71951aeba --- /dev/null +++ b/packages/vite/src/module-runner/__tests_dts__/importMeta.ts @@ -0,0 +1,20 @@ +/** + * Type test to verify ModuleRunnerImportMeta is structurally compatible + * with ImportMeta (including @types/node augmentations). + * + * This replaces `extends ImportMeta` in the interface declaration with a + * test-only assignability check that won't cause TS2717 "subsequent property + * declarations must have the same type" errors in consumer projects using + * skipLibCheck: false with augmented ImportMeta. + */ + +import type { ExpectExtends, ExpectTrue } from '@type-challenges/utils' +import type { ModuleRunnerImportMeta } from '../types' + +export type cases = [ + // Ensure ModuleRunnerImportMeta is assignable to ImportMeta + // (which includes @types/node augmentations: dirname, filename, url, resolve, main) + ExpectTrue>, +] + +export {} diff --git a/packages/vite/src/module-runner/__tests_dts__/tsconfig.json b/packages/vite/src/module-runner/__tests_dts__/tsconfig.json new file mode 100644 index 00000000000000..0ba0f7e065d784 --- /dev/null +++ b/packages/vite/src/module-runner/__tests_dts__/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "isolatedDeclarations": false, + "declaration": false + }, + "include": ["../", "../../types"], + "exclude": ["../**/__tests__"] +} diff --git a/packages/vite/src/module-runner/createImportMeta.ts b/packages/vite/src/module-runner/createImportMeta.ts index f007dadde8e343..5b17d433e46171 100644 --- a/packages/vite/src/module-runner/createImportMeta.ts +++ b/packages/vite/src/module-runner/createImportMeta.ts @@ -25,6 +25,7 @@ export function createDefaultImportMeta( resolve(_id: string, _parent?: string) { throw new Error('[module runner] "import.meta.resolve" is not supported.') }, + main: false, // should be replaced during transformation glob() { throw new Error( @@ -32,8 +33,7 @@ export function createDefaultImportMeta( `file transformation. Make sure to reference it by the full name.`, ) }, - // @types/node adds `main` to `import.meta`, but we don't add that for the defaultImportMeta - } satisfies Omit as any + } } /** diff --git a/packages/vite/src/module-runner/types.ts b/packages/vite/src/module-runner/types.ts index 8ccf4b5edb0a4c..791fa96d5b0900 100644 --- a/packages/vite/src/module-runner/types.ts +++ b/packages/vite/src/module-runner/types.ts @@ -24,10 +24,15 @@ import type { InterceptorOptions } from './sourcemap/interceptor' export type { DefineImportMetadata, SSRImportMetadata } -export interface ModuleRunnerImportMeta extends ImportMeta { +export interface ModuleRunnerImportMeta { url: string env: ImportMetaEnv hot?: ViteHotContext + dirname: string + filename: string + glob: (...args: any[]) => any + resolve(specifier: string, parent?: string): string + main: boolean [key: string]: any }