diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/package.json b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/package.json new file mode 100644 index 0000000000..4dab059e5a --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-typecheck-extends", + "version": "0.0.0", + "private": true +} diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots.toml b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots.toml new file mode 100644 index 0000000000..6d9b851e94 --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots.toml @@ -0,0 +1,8 @@ +[[case]] +name = "check_typecheck_extends" +vp = "local" +env = { VITE_DISABLE_AUTO_INSTALL = "1" } +steps = [ + { argv = ["vp", "check", "--no-fmt", "--no-lint"], continue-on-failure = true }, + { argv = ["vp", "check", "--no-lint"], continue-on-failure = true }, +] diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots/check_typecheck_extends.md b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots/check_typecheck_extends.md new file mode 100644 index 0000000000..be4f597390 --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/snapshots/check_typecheck_extends.md @@ -0,0 +1,14 @@ +# check_typecheck_extends + +## `vp check --no-fmt --no-lint` + +``` +pass: Found no type errors in 2 files (, threads) +``` + +## `vp check --no-lint` + +``` +pass: All 3 files are correctly formatted (, threads) +pass: Found no type errors in 2 files (, threads) +``` diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/src/index.ts b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/src/index.ts new file mode 100644 index 0000000000..3b3d6d4fbc --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/src/index.ts @@ -0,0 +1,2 @@ +const value: number = 42; +export { value }; diff --git a/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/vite.config.ts b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/vite.config.ts new file mode 100644 index 0000000000..4b210c9966 --- /dev/null +++ b/crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/check_typecheck_extends/vite.config.ts @@ -0,0 +1,14 @@ +const base = { + options: { + typeAware: true, + }, +}; + +export default { + lint: { + extends: [base], + options: { + typeCheck: true, + }, + }, +}; diff --git a/packages/cli/binding/src/check/analysis.rs b/packages/cli/binding/src/check/analysis.rs index e02d26fb54..f9093ab903 100644 --- a/packages/cli/binding/src/check/analysis.rs +++ b/packages/cli/binding/src/check/analysis.rs @@ -82,8 +82,21 @@ impl LintMessageKind { /// `typeCheck` requires `typeAware` as a prerequisite — oxlint's type-aware /// analysis must be on for TypeScript diagnostics to surface. pub(super) fn lint_config_type_check_enabled(lint_config: Option<&serde_json::Value>) -> bool { - let options = lint_config.and_then(|config| config.get("options")); - json_bool(options, "typeAware", false) && json_bool(options, "typeCheck", false) + let type_aware = + lint_config.and_then(|config| lint_config_option(config, "typeAware")).unwrap_or(false); + let type_check = + lint_config.and_then(|config| lint_config_option(config, "typeCheck")).unwrap_or(false); + type_aware && type_check +} + +fn lint_config_option(config: &serde_json::Value, key: &str) -> Option { + if let Some(value) = config.get("options").and_then(|options| options.get(key)) { + return Some(value.as_bool().unwrap_or(false)); + } + + config.get("extends").and_then(serde_json::Value::as_array).and_then(|configs| { + configs.iter().filter_map(|config| lint_config_option(config, key)).last() + }) } /// Read a boolean `key` from a JSON object, falling back to `default` when the @@ -281,6 +294,27 @@ mod tests { assert_eq!(kind.issue_heading(), "Type errors found"); } + #[test] + fn lint_config_type_check_resolves_extends() { + let config = json!({ + "extends": [ + { "options": { "typeAware": false } }, + { + "extends": [{ "options": { "typeAware": true } }], + "options": { "typeCheck": false } + } + ], + "options": { "typeCheck": true } + }); + assert!(lint_config_type_check_enabled(Some(&config))); + + let config = json!({ + "extends": [{ "options": { "typeAware": true, "typeCheck": true } }], + "options": { "typeAware": false } + }); + assert!(!lint_config_type_check_enabled(Some(&config))); + } + #[test] fn lint_config_type_check_enabled_rejects_non_bool_values() { assert!(!lint_config_type_check_enabled(Some(&json!({