From a99c5d237651ba8686bfde94be7ef1b222324d29 Mon Sep 17 00:00:00 2001 From: MartinFerret Date: Fri, 6 Nov 2026 11:52:28 +0100 Subject: [PATCH 1/2] Update noUncheckedSideEffectImports docs for TypeScript 6.0 and library authors --- .../options/noUncheckedSideEffectImports.md | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md b/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md index e6d862efc733..64fe1fec689c 100644 --- a/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md +++ b/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md @@ -33,8 +33,8 @@ When `--noUncheckedSideEffectImports` is enabled, TypeScript will error if it ca ```ts import "oops-this-module-does-not-exist"; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// error: Cannot find module 'oops-this-module-does-not-exist' or its corresponding -// type declarations. +// error: Cannot find module or type declarations for side-effect import of +// 'oops-this-module-does-not-exist'. ``` When enabling this option, some working code may now receive an error, like in the CSS example above. @@ -50,3 +50,44 @@ declare module "*.css" {} In fact, you might already have a file like this in your project! For example, running something like `vite init` might create a similar `vite-env.d.ts`. + +#### Side effect imports of CSS from packages + +A wildcard declaration like `declare module "*.css" {}` only matches specifiers that end in `.css`. +If a package exposes its stylesheet through a subpath without that extension, and that subpath has no `"types"` condition in the package's `"exports"`, importing it still causes an error: + +```ts +import "library-name/css"; +// ~~~~~~~~~~~~~~~~~~ +// error: Cannot find module or type declarations for side-effect import of +// 'library-name/css'. +``` + +If you maintain such a package, you can avoid this error for your users in one of two ways. + +The first is to add a `"types"` condition to the subpath in your `package.json`, pointing to a declaration file which only contains `export {};`: + +```json +{ + "exports": { + "./css": { + "types": "./dist/style.d.ts", + "default": "./dist/style.css" + } + } +} +``` + +```ts +// ./dist/style.d.ts +export {}; +``` + +The second is to expose the stylesheet through a subpath that ends in `.css`, like `library-name/style.css`, so that a `"*.css"` declaration in your users' projects matches it. + +If you use a package which does neither, you can declare the specifier yourself in a global file: + +```ts +// ./src/globals.d.ts +declare module "library-name/css"; +``` From 0727968708c5cb9b8b491f2f51d8057b09693bbc Mon Sep 17 00:00:00 2001 From: MartinFerret Date: Fri, 6 Nov 2026 11:58:05 +0100 Subject: [PATCH 2/2] Mention the .d.css.ts approach and disabling the option for bundler-managed assets --- .../options/noUncheckedSideEffectImports.md | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md b/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md index 64fe1fec689c..b3ed4602da52 100644 --- a/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md +++ b/packages/tsconfig-reference/copy/en/options/noUncheckedSideEffectImports.md @@ -54,7 +54,7 @@ For example, running something like `vite init` might create a similar `vite-env #### Side effect imports of CSS from packages A wildcard declaration like `declare module "*.css" {}` only matches specifiers that end in `.css`. -If a package exposes its stylesheet through a subpath without that extension, and that subpath has no `"types"` condition in the package's `"exports"`, importing it still causes an error: +If a package exposes its stylesheet through a subpath without that extension, and TypeScript can't find a declaration file for that subpath, importing it still causes an error: ```ts import "library-name/css"; @@ -63,9 +63,19 @@ import "library-name/css"; // 'library-name/css'. ``` -If you maintain such a package, you can avoid this error for your users in one of two ways. +If you maintain such a package, the recommended fix is to ship a declaration file next to the stylesheet. +For a stylesheet at `./dist/style.css`, that file is `./dist/style.d.css.ts`: -The first is to add a `"types"` condition to the subpath in your `package.json`, pointing to a declaration file which only contains `export {};`: +```ts +// ./dist/style.d.css.ts +export {}; +``` + +Users of the package then need to enable [`allowArbitraryExtensions`](#allowArbitraryExtensions). +Otherwise, TypeScript reports error TS6263, because the import resolves to a declaration file for a file with a non-standard extension. + +Alternatively, you can add a `"types"` condition to the subpath in your `package.json`, pointing to a declaration file which only contains `export {};`. +This works without any setting in your users' projects: ```json { @@ -83,11 +93,14 @@ The first is to add a `"types"` condition to the subpath in your `package.json`, export {}; ``` -The second is to expose the stylesheet through a subpath that ends in `.css`, like `library-name/style.css`, so that a `"*.css"` declaration in your users' projects matches it. +You can also expose the stylesheet through a subpath that ends in `.css`, like `library-name/style.css`, so that a `"*.css"` declaration in your users' projects matches it. -If you use a package which does neither, you can declare the specifier yourself in a global file: +If you use a package which does none of these, you can declare the specifier yourself in a global file: ```ts // ./src/globals.d.ts declare module "library-name/css"; ``` + +If a bundler already validates imports of non-code files like CSS in your project, you can instead set `noUncheckedSideEffectImports` to `false` and let the bundler handle them. +TypeScript then no longer reports any unresolved side effect import.