Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .changeset/fix-type-inference-imported-bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
"@biomejs/biome": patch
---

Fixed [#7905](https://github.com/biomejs/biome/issues/7905). Improved the accuracy of type-aware lint rules when analyzing re-exported functions and values.

Previously, when a binding was imported from another module, its type was not correctly inferred during the type analysis phase. This caused type-aware lint rules to fail to detect issues when working with re-exported imports.

The following rules now correctly handle re-exported imports:
- [`useAwaitThenable`](https://biomejs.dev/linter/rules/use-await-thenable/)
- [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/)
- [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/)
- [`useArraySortCompare`](https://biomejs.dev/linter/rules/use-array-sort-compare/)

Example of now-working detection:

```ts
// getValue.ts
export async function getValue(): Promise<number> {
return 42;
}

// reexport.ts
export { getValue } from "./getValue";

// index.ts
import { getValue } from "./reexport";

// Previously: no diagnostic (type was unknown)
// Now: correctly detects that getValue() returns a Promise
await getValue(); // Valid - properly awaited
getValue(); // Diagnostic - floating promise
```
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* should not generate diagnostics */

export async function getValue(): Promise<number> {
return 42;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: getValue.ts
---
# Input
```ts
/* should not generate diagnostics */
export async function getValue(): Promise<number> {
return 42;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* should generate diagnostics */

import { getValue } from "./reexport";

function test() {
// Invalid: Promise is not handled (no await, no .then, no void operator)
getValue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: index.ts
---
# Input
```ts
/* should generate diagnostics */
import { getValue } from "./reexport";
function test() {
// Invalid: Promise is not handled (no await, no .then, no void operator)
getValue();
}
```

# Diagnostics
```
index.ts:7:5 lint/nursery/noFloatingPromises ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i A "floating" Promise was found, meaning it is not properly handled and could lead to ignored errors or unexpected behavior.
5 │ function test() {
6// Invalid: Promise is not handled (no await, no .then, no void operator)
> 7getValue();
^^^^^^^^^^^
8}
9 │
i This happens when a Promise is not awaited, lacks a `.catch` or `.then` rejection handler, or is not explicitly ignored using the `void` operator.
i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* should not generate diagnostics */

export { getValue } from "./getValue";
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: reexport.ts
---
# Input
```ts
/* should not generate diagnostics */
export { getValue } from "./getValue";
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* should not generate diagnostics */

export async function getValue(): Promise<number> {
return 42;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: getValue.ts
---
# Input
```ts
/* should not generate diagnostics */
export async function getValue(): Promise<number> {
return 42;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* should not generate diagnostics */

import { getValue } from "./reexport";

async function test() {
// Valid: Promise is properly handled with await
await getValue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: index.ts
---
# Input
```ts
/* should not generate diagnostics */
import { getValue } from "./reexport";
async function test() {
// Valid: Promise is properly handled with await
await getValue();
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* should not generate diagnostics */

export { getValue } from "./getValue";
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: reexport.ts
---
# Input
```ts
/* should not generate diagnostics */
export { getValue } from "./getValue";
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* should not generate diagnostics */

export async function getValue(): Promise<number> {
return 42;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: getValue.ts
---
# Input
```ts
/* should not generate diagnostics */
export async function getValue(): Promise<number> {
return 42;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* should generate diagnostics */

import { getValue } from "./reexport";

function test() {
// Invalid: Promise used in boolean context (if condition)
if (getValue()) {
console.log("test");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: index.ts
---
# Input
```ts
/* should generate diagnostics */
import { getValue } from "./reexport";
function test() {
// Invalid: Promise used in boolean context (if condition)
if (getValue()) {
console.log("test");
}
}
```

# Diagnostics
```
index.ts:7:9 lint/nursery/noMisusedPromises ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
i A Promise was found where a conditional was expected.
5 │ function test() {
6// Invalid: Promise used in boolean context (if condition)
> 7if (getValue()) {
│ ^^^^^^^^^^
8 │ console.log("test");
9 │ }
i A Promise is always truthy, so this is most likely a mistake.
i You may have intended to `await` the Promise instead.
i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* should not generate diagnostics */

export { getValue } from "./getValue";
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: reexport.ts
---
# Input
```ts
/* should not generate diagnostics */
export { getValue } from "./getValue";
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* should not generate diagnostics */

export async function getValue(): Promise<number> {
return 42;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: getValue.ts
---
# Input
```ts
/* should not generate diagnostics */
export async function getValue(): Promise<number> {
return 42;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* should not generate diagnostics */

import { getValue } from "./reexport";

async function test() {
// Valid: Promise returned from async function
return getValue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: index.ts
---
# Input
```ts
/* should not generate diagnostics */
import { getValue } from "./reexport";
async function test() {
// Valid: Promise returned from async function
return getValue();
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* should not generate diagnostics */

export { getValue } from "./getValue";
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: reexport.ts
---
# Input
```ts
/* should not generate diagnostics */
export { getValue } from "./getValue";
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* should not generate diagnostics */

export function getArray(): number[] {
return [1, 2, 3];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: crates/biome_js_analyze/tests/spec_tests.rs
expression: getArray.ts
---
# Input
```ts
/* should not generate diagnostics */
export function getArray(): number[] {
return [1, 2, 3];
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* should generate diagnostics */

import { getArray } from "./reexport";

function test() {
// Invalid: Number array sorted without compare function
getArray().sort();
}
Loading
Loading