Environment information
Details
CLI:
Version: 2.5.14
Platform:
CPU Architecture: aarch64
OS: macos
Environment:
JS_RUNTIME_NAME: node
NODE_PACKAGE_MANAGER: pnpm/11.24.0
Biome Configuration:
Status: Loaded successfully.
Path: biome.json
Linter enabled: true
Rule name
nursery/useExhaustiveSwitchCases
Playground link
Not reproducible in the playground (needs two workspace packages). Full repro below.
What happened?
useExhaustiveSwitchCases does not report a non-exhaustive switch when the discriminant's type is a union derived as (typeof ARR)[number] and imported from another workspace package. The same switch over a locally declared copy of the union is reported. #6929 and #11730 report similar gaps and are closed; this is the workspace-package import case, which still reproduces on 2.5.14.
Repro (pnpm workspace):
package.json { "devDependencies": { "@biomejs/biome": "2.5.14" } }
pnpm-workspace.yaml packages: ["packages/*"]
biome.json { "linter": { "enabled": true, "rules": { "nursery": { "useExhaustiveSwitchCases": "error" } } } }
packages/lib/package.json { "name": "@repro/lib", "version": "1.0.0", "main": "src/index.ts", "types": "src/index.ts" }
packages/app/package.json { "name": "@repro/app", "version": "1.0.0", "dependencies": { "@repro/lib": "workspace:*" } }
packages/lib/src/index.ts:
export const S = ["a", "b", "c"] as const;
export type S = (typeof S)[number];
packages/app/src/cross.ts (imported union, case "c" missing, no default):
import type { S } from "@repro/lib";
export function f(x: S): number {
switch (x) {
case "a":
return 1;
case "b":
return 2;
}
return 0;
}
packages/app/src/local.ts (same union declared locally, same missing case):
const L = ["a", "b", "c"] as const;
type L = (typeof L)[number];
export function g(x: L): number {
switch (x) {
case "a":
return 1;
case "b":
return 2;
}
return 0;
}
Steps: pnpm install, then pnpm exec biome lint packages.
Result: only local.ts is reported (The switch statement is not exhaustive ... These cases are missing: - "c"). pnpm exec biome lint packages/app/src/cross.ts prints Checked 1 file in 2ms. No fixes applied. with no diagnostic.
Expected result
cross.ts is reported with the missing case "c", as local.ts is.
Code of Conduct
Environment information
Details
CLI: Version: 2.5.14 Platform: CPU Architecture: aarch64 OS: macos Environment: JS_RUNTIME_NAME: node NODE_PACKAGE_MANAGER: pnpm/11.24.0 Biome Configuration: Status: Loaded successfully. Path: biome.json Linter enabled: trueRule name
nursery/useExhaustiveSwitchCasesPlayground link
Not reproducible in the playground (needs two workspace packages). Full repro below.
What happened?
useExhaustiveSwitchCasesdoes not report a non-exhaustiveswitchwhen the discriminant's type is a union derived as(typeof ARR)[number]and imported from another workspace package. The same switch over a locally declared copy of the union is reported. #6929 and #11730 report similar gaps and are closed; this is the workspace-package import case, which still reproduces on 2.5.14.Repro (pnpm workspace):
packages/lib/src/index.ts:packages/app/src/cross.ts(imported union, case "c" missing, no default):packages/app/src/local.ts(same union declared locally, same missing case):Steps:
pnpm install, thenpnpm exec biome lint packages.Result: only
local.tsis reported (The switch statement is not exhaustive ... These cases are missing: - "c").pnpm exec biome lint packages/app/src/cross.tsprintsChecked 1 file in 2ms. No fixes applied.with no diagnostic.Expected result
cross.tsis reported with the missing case"c", aslocal.tsis.Code of Conduct