Skip to content

feat(types): make ImportMetaEnv strictly available #19077

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
6 changes: 6 additions & 0 deletions docs/guide/env-and-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ To achieve this, you can create an `vite-env.d.ts` in `src` directory, then augm
```typescript [vite-env.d.ts]
/// <reference types="vite/client" />

interface ViteTypeOptions {
// By adding this line, you can make the type of ImportMetaEnv strict
// to disallow unknown keys.
// strictImportMetaEnv: unknown
}

interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
// more env variables...
Expand Down
21 changes: 21 additions & 0 deletions packages/vite/src/node/__tests_dts__/typeOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This file tests `ViteTypeOptions` in `packages/vite/types/importMeta.d.ts`
import type { ExpectFalse, ExpectTrue } from '@type-challenges/utils'

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface TypeOptions1 {}
interface TypeOptions2 {
strictImportMetaEnv: unknown
}
interface TypeOptions3 {
unknownKey: unknown
}

type IsEnabled<Opts, Key extends string> = Key extends keyof Opts ? true : false

export type cases = [
ExpectFalse<IsEnabled<TypeOptions1, 'strictImportMetaEnv'>>,
ExpectTrue<IsEnabled<TypeOptions2, 'strictImportMetaEnv'>>,
ExpectFalse<IsEnabled<TypeOptions3, 'strictImportMetaEnv'>>,
]

export {}
11 changes: 10 additions & 1 deletion packages/vite/types/importMeta.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@
// Thus cannot contain any top-level imports
// <https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation>

// This is tested in `packages/vite/src/node/__tests_dts__/typeOptions.ts`
// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- to allow extending by users
interface ViteTypeOptions {
// strictImportMetaEnv: unknown
}

type ImportMetaEnvFallbackKey =
'strictImportMetaEnv' extends keyof ViteTypeOptions ? never : string

interface ImportMetaEnv {
[key: string]: any
[key: ImportMetaEnvFallbackKey]: any
BASE_URL: string
MODE: string
DEV: boolean
Expand Down