Skip to content

Commit

Permalink
fix(noTypeOnlyImportAttributes): ignore .cts files
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Oct 22, 2024
1 parent a1ae7bf commit bf8a6c0
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 8 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

- `noSuspiciousSemicolonInJsx` now catches suspicious semicolons in React fragments. Contributed by @vasucp1207

- The syntax rule `noTypeOnlyImportAttributes` now ignores `.cts` files ([#4361](https://github.com/biomejs/biome/issues/4361)).

Since TypeScript 5.3, type-only imports can be associated to an import attribute in CommonJS-enabled files.
See the [TypeScript docs](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-3.html#stable-support-resolution-mode-in-import-types).

The following code is no longer reported as a syntax error:

```cts
import type { TypeFromRequire } from "pkg" with {
"resolution-mode": "require"
};
```

Note that this is only allowed in files ending with the `cts` extension.

Contributed by @Conaclos

### CLI

#### Enhancements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ declare_syntax_rule! {
///
/// ## Examples
///
/// ```js
/// ```ts
/// let foo!: string = "bar";
/// ```
pub NoInitializerWithDefinite {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,23 @@ use biome_rowan::{AstNode, AstSeparatedList, TextRange};
declare_syntax_rule! {
/// Disallow type-only imports and exports with import attributes.
///
/// There is one exception: TypeScript 5.3 and above allow this in CommonJS files, e.g. files ending with the `.cts` extension.
/// See the [TypeScript docs](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-3.html#stable-support-resolution-mode-in-import-types).
///
/// ## Examples
///
/// ```js
/// ### Invalid
///
/// ```ts
/// import type { A } from "./a.json" with { type: "json" };
/// ```
///
/// ### Valid
///
/// ```cts
/// import type { A } from "./a.json" with { "resolution-mode": "require" };
/// ```
///
pub NoTypeOnlyImportAttributes {
version: "1.5.0",
name: "noTypeOnlyImportAttributes",
Expand All @@ -27,6 +39,11 @@ impl Rule for NoTypeOnlyImportAttributes {
type Options = ();

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let extension = ctx.file_path().extension()?;
if extension.as_encoded_bytes() == b"cts" {
// Ignore `*.cts`
return None;
}
let module_item = ctx.query();
match module_item {
AnyJsModuleItem::AnyJsStatement(_) => None,
Expand Down
4 changes: 2 additions & 2 deletions crates/biome_js_analyze/tests/spec_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use biome_test_utils::{
use std::ops::Deref;
use std::{ffi::OsStr, fs::read_to_string, path::Path, slice};

tests_macros::gen_tests! {"tests/specs/**/*.{cjs,js,jsx,tsx,ts,json,jsonc,svelte}", crate::run_test, "module"}
tests_macros::gen_tests! {"tests/suppression/**/*.{cjs,js,jsx,tsx,ts,json,jsonc,svelte}", crate::run_suppression_test, "module"}
tests_macros::gen_tests! {"tests/specs/**/*.{cjs,cts,js,jsx,tsx,ts,json,jsonc,svelte}", crate::run_test, "module"}
tests_macros::gen_tests! {"tests/suppression/**/*.{cjs,cts,js,jsx,tsx,ts,json,jsonc,svelte}", crate::run_suppression_test, "module"}

fn run_test(input: &'static str, _: &str, _: &str, _: &str) {
register_leak_checker();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { TypeFromRequire } from "pkg" with {
"resolution-mode": "require"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: valid.cts
---
# Input
```cts
import type { TypeFromRequire } from "pkg" with {
"resolution-mode": "require"
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
14 changes: 10 additions & 4 deletions crates/biome_js_syntax/src/file_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,16 @@ impl JsFileSource {
}
}
Language::TypeScript { .. } => {
if matches!(self.variant, LanguageVariant::Jsx) {
"tsx"
} else {
"ts"
match self.variant {
LanguageVariant::Standard => "ts",
LanguageVariant::StandardRestricted => {
// This could also be `mts`.
// We choose `cts` because we expect this extension to be more widely used.
// Moreover, it allows more valid syntax such as `import type` with import
// attributes (See `noTypeOnlyImportAttributes` syntax rule).
"cts"
}
LanguageVariant::Jsx => "tsx",
}
}
}
Expand Down

0 comments on commit bf8a6c0

Please sign in to comment.