Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

arendjr
Copy link
Contributor

@arendjr arendjr commented Jul 4, 2025

Summary

Fixed #7423: Type inference now recognises index signatures and their accesses when they are being indexed as a string.

Replaces #6647, which was closed unintentionally.

Example

type BagOfPromises = {
    // This is an index signature definition. It declares that instances of type
    // `BagOfPromises` can be indexed using arbitrary strings.
    [property: string]: Promise<void>;
};

let bag: BagOfPromises = {};
// Because `bag.iAmAPromise` is equivalent to `bag["iAmAPromise"]`, this is
// considered an access to the string index, and a Promise is expected.
bag.iAmAPromise;

Test Plan

Test cases added.

@arendjr arendjr requested review from a team July 4, 2025 16:13
@changeset-bot
Copy link

changeset-bot bot commented Jul 4, 2025

🦋 Changeset detected

Latest commit: b52bf24

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Type-Inference Area: type inference labels Jul 4, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Walkthrough

This PR adds index-signature support across the type system and the linter. It introduces TypeMemberKind::IndexSignature and formatter support, implements TsIndexSignature handling, moves element/index access logic onto ResolvedTypeData with new finder APIs (find_member, find_index_signature_with_ty, find_element_type_at_index, find_type_of_elements_from_index) and ElementTypeReference, and refactors flattening/expressions.rs (including flattened_destructure) to use these helpers. Two type predicate methods were renamed to include literal checks and relevant tests were updated. New noFloatingPromises tests and a resolver tsconfig fixture were added.

Suggested reviewers

  • ematipico
  • dyc3

Pre-merge checks (3 passed, 2 warnings)

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning This PR also renames unrelated predicates (is_number/is_string), updates module graph tests, and adds a tsconfig fixture for resolver tests—changes that don’t directly support index signature inference or the noFloatingPromises rule and would be clearer if split into separate PRs. Please extract the predicate renames, module graph test updates, and new tsconfig fixture into their own PRs so that this one remains focused solely on index signature support and floating-promise detection.
Docstring Coverage ⚠️ Warning Docstring coverage is 64.10% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title “feat(core): implement support for index signatures” clearly and concisely summarises the primary change—adding support for index signatures—without extraneous detail or ambiguity. It aligns with the core objective of the PR and would be immediately understandable to reviewers.
Linked Issues Check ✅ Passed The changes implement recognition of string index signatures in type inference (in local_inference, type_data, flattening, and helpers), update the linter’s noFloatingPromises rule with new invalid tests to catch floating promises on indexed properties, and thereby satisfy the primary requirements of issue #7423.
Description Check ✅ Passed The description directly outlines the fix for issue #7423, explains that it restores PR #6647, provides a concrete TypeScript example of index signature access, and notes that test cases were added, so it is clearly related to the changeset.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch index-signatures

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the A-Resolver Area: resolver label Sep 9, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
crates/biome_js_type_info/src/helpers.rs (2)

45-68: Document why arrays are always “optional” here

Great helper. For arrays, is_optional: true regardless of index is intentional for destructuring (values may be missing). Please add a brief note in the doc-comment to avoid confusion with TypeScript’s default indexed access (which isn’t optional unless noUncheckedIndexedAccess is on).

Apply this small doc tweak:

 /// Returns the type of an element at a given index, if this object is an
 /// array or a tuple.
+/// Note: For `Array<T>`, the returned element is always marked optional
+/// (may be `undefined`) to reflect JS destructuring semantics.
 pub fn find_element_type_at_index(

330-347: Clarify module-ID expectations for into_reference

Constructing a ResolvedTypeId with only level() intentionally defers module-ID application to consumers. A short comment would prevent misuse at call sites.

Suggested doc tweak:

 impl ElementTypeReference {
     pub fn into_reference(self, resolver: &mut dyn TypeResolver) -> TypeReference {
-        if self.is_optional {
+        // Note: The returned reference encodes the current resolver level only.
+        // Owners must apply their module ID via `apply_module_id_to_reference(...)`
+        // before resolving.
+        if self.is_optional {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac17183 and 8621383.

⛔ Files ignored due to path filters (3)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_country_info.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_vfile.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (11)
  • .changeset/infinite-indices-infer.md (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts (1 hunks)
  • crates/biome_js_type_info/src/flattening/expressions.rs (7 hunks)
  • crates/biome_js_type_info/src/format_type_info.rs (1 hunks)
  • crates/biome_js_type_info/src/helpers.rs (4 hunks)
  • crates/biome_js_type_info/src/local_inference.rs (1 hunks)
  • crates/biome_js_type_info/src/resolver.rs (1 hunks)
  • crates/biome_js_type_info/src/type.rs (2 hunks)
  • crates/biome_js_type_info/src/type_data.rs (6 hunks)
  • crates/biome_module_graph/tests/spec_tests.rs (4 hunks)
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: In changeset files, only use #### or ##### headers; avoid other header levels
Changeset descriptions should use past tense for what you did (e.g., "Added...")
Describe current Biome behavior in present tense within changesets (e.g., "Biome now supports...")
For bug fixes in changesets, start with a link to the issue (e.g., "Fixed #1234: ...")
When referencing rules or assists in changesets, include links to their documentation pages
Include a minimal code block in the changeset when applicable to demonstrate the change
End every sentence in the changeset description with a period

Files:

  • .changeset/infinite-indices-infer.md
crates/biome_js_type_info/src/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

crates/biome_js_type_info/src/**/*.rs: Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
crates/biome_js_type_info/src/local_inference.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

Local inference must not perform type resolution; it should only create TypeReference::Qualifier entries from syntax

Files:

  • crates/biome_js_type_info/src/local_inference.rs
🧠 Learnings (15)
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
PR: biomejs/biome#7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/**/*.jsonc : Use .jsonc files containing arrays of code snippets for snapshot tests that require multiple script snippets

Applied to files:

  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : Set the language field in declare_lint_rule! to the most specific applicable language (js/jsx/ts/tsx)

Applied to files:

  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_type_info/src/type.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_module_graph/tests/spec_tests.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_tests.rs : Create tests/spec_tests.rs in the biome_html_formatter crate that generates tests via tests_macros::gen_tests! for all HTML files at tests/specs/html/**/*.html

Applied to files:

  • crates/biome_module_graph/tests/spec_tests.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in biome_lsp’s server.tests.rs

Applied to files:

  • crates/biome_module_graph/tests/spec_tests.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference resolves TypeReference::Import across modules into TypeReference::Resolved using the module graph; do not cache full-inference results

Applied to files:

  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/nursery/** : Place snapshot test cases for new rules under tests/specs/nursery/<ruleName>/ with files prefixed by invalid/valid

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference may resolve qualifiers to local declarations or globals (TypeReference::Resolved), mark imported bindings as TypeReference::Import, and set unresolved to TypeReference::Unknown; it must not look beyond the current module

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/flattening.rs : Flatten types only after references are resolved; e.g., addition of two TypeData::Number flattens to TypeData::Number, otherwise often to TypeData::String

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/local_inference.rs : Local inference must not perform type resolution; it should only create TypeReference::Qualifier entries from syntax

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
🧬 Code graph analysis (6)
crates/biome_js_type_info/src/resolver.rs (1)
crates/biome_js_type_info/src/type_data.rs (1)
  • is_index_signature_with_ty (934-939)
crates/biome_js_type_info/src/format_type_info.rs (4)
crates/biome_js_type_info/src/resolver.rs (1)
  • ty (518-520)
crates/biome_js_type_info/src/type_data.rs (1)
  • ty (545-550)
crates/biome_module_graph/src/js_module_info/binding.rs (1)
  • ty (92-94)
crates/biome_formatter/src/lib.rs (1)
  • write (1323-1330)
crates/biome_module_graph/tests/spec_tests.rs (1)
crates/biome_js_type_info/src/type.rs (2)
  • is_string_or_string_literal (215-222)
  • is_number_or_number_literal (181-188)
crates/biome_js_type_info/src/type_data.rs (1)
crates/biome_js_type_info/src/resolver.rs (13)
  • from (322-324)
  • from (329-331)
  • from (401-406)
  • from (411-416)
  • new (51-53)
  • new (290-295)
  • index (73-75)
  • index (297-299)
  • resolver_id (103-105)
  • resolver_id (367-369)
  • is_index_signature_with_ty (482-486)
  • ty (518-520)
  • name (499-501)
crates/biome_js_type_info/src/local_inference.rs (2)
crates/biome_js_type_info/src/resolver.rs (4)
  • name (499-501)
  • ty (518-520)
  • new (51-53)
  • new (290-295)
crates/biome_js_type_info/src/type_data.rs (6)
  • name (951-953)
  • name (999-1005)
  • ty (545-550)
  • new (39-43)
  • new (1425-1429)
  • new (1460-1470)
crates/biome_js_type_info/src/helpers.rs (2)
crates/biome_js_type_info/src/resolver.rs (8)
  • ty (518-520)
  • from (322-324)
  • from (329-331)
  • from (401-406)
  • from (411-416)
  • id (68-70)
  • new (51-53)
  • new (290-295)
crates/biome_js_type_info/src/type_data.rs (16)
  • ty (545-550)
  • from (174-176)
  • from (180-182)
  • from (186-188)
  • from (192-194)
  • from (198-200)
  • from (204-206)
  • from (210-212)
  • from (216-218)
  • from (222-224)
  • from (228-230)
  • from (234-236)
  • instance_of (295-297)
  • new (39-43)
  • new (1425-1429)
  • new (1460-1470)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Check Dependencies
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: autofix
🔇 Additional comments (22)
crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json (1)

1-9: LGTM!

The TypeScript configuration file is properly structured with path aliasing for resolver test cases.

.changeset/infinite-indices-infer.md (1)

10-21: Excellent example demonstrating index signatures.

The code example clearly shows how string index signatures work with both bracket and dot notation. The comment explains the equivalence well.

crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts (1)

1-9: LGTM! Good test case for index signatures.

The test properly exercises the new index signature functionality with Promise types, testing both direct property access and destructuring patterns.

crates/biome_js_type_info/src/format_type_info.rs (1)

352-354: Clean implementation of index signature formatting.

The formatting as [<ty>] follows TypeScript's standard notation nicely.

crates/biome_js_type_info/src/resolver.rs (1)

482-486: Proper module ID handling for index signatures.

The implementation correctly applies the module ID transformation before invoking the predicate, maintaining consistency with other resolver methods.

crates/biome_module_graph/tests/spec_tests.rs (1)

695-695: Consistent API updates across tests.

The test assertions properly reflect the renamed methods is_string_or_string_literal() and is_number_or_number_literal(), maintaining test coverage for the broader type checking.

Also applies to: 742-742, 1621-1621, 1751-1751, 1757-1757

crates/biome_js_type_info/src/local_inference.rs (2)

2051-2069: Clean refactor using early return pattern.

The getter implementation now uses the ? operator for cleaner error handling whilst maintaining the same functionality.


2071-2086: Well-structured index signature implementation.

The implementation properly extracts both key and value types from the index signature syntax, correctly creating a TypeMemberKind::IndexSignature with the appropriate types.

crates/biome_js_type_info/src/type.rs (1)

181-189: Literal-aware number/string predicates look correct

Covers both primitive and literal variants; comparisons against GLOBAL_NUMBER_ID/GLOBAL_STRING_ID are consistent.

Also applies to: 215-223

crates/biome_js_type_info/src/flattening/expressions.rs (7)

10-12: Import additions match the new destructure flow

All good; keeps the surface tidy.


122-122: Nice extraction

Routing Destructure through a helper improves readability and keeps this match lean.


125-133: Index access path correctly resolver-aware

find_element_type_at_index + into_reference + resolve_and_get is the right, ID-safe sequence.


264-267: Tuple-as-Array member lookup is spot on

Using find_member on Array avoids manual iteration and respects prototype semantics.


352-356: Call-signature lookup modernised

Switch to find_member for InstanceOf and Interface/Object branches is cleaner and avoids raw-member trawling.

Also applies to: 361-365


373-437: Destructure handling reads well and applies resolver IDs correctly

  • Correctly applies module IDs before member lookups and deref_ty resolution.
  • RestFrom defers to helper, and RestExcept preserves order with dedup.

Nice extraction—my future self thanks you.


293-301: Replace stale is_string predicates in flattening/expressions.rs
Update all occurrences of

.find_index_signature_with_ty(resolver, |ty| ty.is_string())

to

.find_index_signature_with_ty(resolver, |ty| ty.is_string_or_string_literal())

at crates/biome_js_type_info/src/flattening/expressions.rs lines 297, 397 and 428.

⛔ Skipped due to learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : Avoid unnecessary string allocations in rules; compare against &str or TokenText instead of calling to_string()
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/flattening.rs : Flatten types only after references are resolved; e.g., addition of two TypeData::Number flattens to TypeData::Number, otherwise often to TypeData::String
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Prefer Box<[Box<str>]> over Vec<String> for lists of strings in options for memory efficiency
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/**/src/**/*.rs : Prefer Box<[_]> over Vec<_> for Signals when emitting multiple diagnostics
crates/biome_js_type_info/src/type_data.rs (4)

233-237: From for TypeData is a sensible convenience

Keeps constructors uniform with other variants.


855-861: Tuple APIs: clear and resolver-safe

  • get_element correctly falls back to the final rest element.
  • slice_from applies resolver_id to element tys, avoiding cross-module leaks.

LGTM.

Also applies to: 863-877


934-939: Index signature predicate on TypeMember is minimal and correct

Matches the resolver wrapper API and keeps the check local.


958-966: TypeMemberKind: IndexSignature integration looks complete

has_name/name behaviour aligns with TS semantics; enums and match arms updated consistently.

Also applies to: 971-976, 1001-1004

crates/biome_js_type_info/src/helpers.rs (2)

612-617: New matchers look good

The added is_never_keyword, is_number, and is_string matchers align with the macro pattern used elsewhere and keep APIs consistent.


70-91: Drop manual module-ID application; current code is correct
ResolvedTypeMember::is_index_signature_with_ty (in resolver.rs) already applies the module ID via apply_module_id_to_reference before invoking the predicate, so ty is correctly namespaced and can be passed directly to resolver.resolve_and_get.

Likely an incorrect or invalid review comment.

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 9, 2025

CodSpeed Performance Report

Merging #6710 will improve performances by 6.66%

Comparing index-signatures (b52bf24) with main (ac17183)

Summary

⚡ 1 improvements
✅ 132 untouched benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
json_analyzer[big5-added_15586211152145260264.json] 463.5 µs 434.5 µs +6.66%

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
crates/biome_js_type_info/src/helpers.rs (1)

104-124: LGTM! Proper array synthesis without module ID application.

The code correctly uses GLOBAL_ARRAY_ID directly without applying module IDs, which aligns with the learnings about global constants belonging to the global resolver.

🧹 Nitpick comments (1)
crates/biome_js_type_info/src/type_data.rs (1)

963-966: Ensure consistent variant ordering in the enum.

The IndexSignature variant is inserted between Getter and Named. Consider if this placement is intentional for semantic grouping or if alphabetical ordering would be clearer.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8621383 and ba74fb0.

⛔ Files ignored due to path filters (4)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_country_info.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_vfile.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (12)
  • .changeset/infinite-indices-infer.md (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts (1 hunks)
  • crates/biome_js_type_info/src/flattening/expressions.rs (7 hunks)
  • crates/biome_js_type_info/src/format_type_info.rs (1 hunks)
  • crates/biome_js_type_info/src/helpers.rs (4 hunks)
  • crates/biome_js_type_info/src/local_inference.rs (1 hunks)
  • crates/biome_js_type_info/src/resolver.rs (1 hunks)
  • crates/biome_js_type_info/src/type.rs (2 hunks)
  • crates/biome_js_type_info/src/type_data.rs (6 hunks)
  • crates/biome_module_graph/tests/spec_tests.rs (4 hunks)
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • crates/biome_module_graph/tests/spec_tests.rs
  • .changeset/infinite-indices-infer.md
  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
  • crates/biome_js_type_info/src/local_inference.rs
🧰 Additional context used
📓 Path-based instructions (7)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
crates/biome_js_type_info/src/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

crates/biome_js_type_info/src/**/*.rs: Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Files:

  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Files:

  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Files:

  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
🧠 Learnings (11)
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/nursery/** : Place snapshot test cases for new rules under tests/specs/nursery/<ruleName>/ with files prefixed by invalid/valid

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
PR: biomejs/biome#7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-09-09T18:10:05.061Z
Learnt from: arendjr
PR: biomejs/biome#6710
File: crates/biome_js_type_info/src/helpers.rs:102-124
Timestamp: 2025-09-09T18:10:05.061Z
Learning: Global constants like GLOBAL_ARRAY_ID are stored by the global resolver and should never have module IDs applied to them. Module IDs only apply to module resolvers, not global resolvers. When working with global type constants, use them directly without module ID transformations.

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference resolves TypeReference::Import across modules into TypeReference::Resolved using the module graph; do not cache full-inference results

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference may resolve qualifiers to local declarations or globals (TypeReference::Resolved), mark imported bindings as TypeReference::Import, and set unresolved to TypeReference::Unknown; it must not look beyond the current module

Applied to files:

  • crates/biome_js_type_info/src/helpers.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/flattening.rs : Flatten types only after references are resolved; e.g., addition of two TypeData::Number flattens to TypeData::Number, otherwise often to TypeData::String

Applied to files:

  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/local_inference.rs : Local inference must not perform type resolution; it should only create TypeReference::Qualifier entries from syntax

Applied to files:

  • crates/biome_js_type_info/src/flattening/expressions.rs
  • crates/biome_js_type_info/src/type_data.rs
🧬 Code graph analysis (3)
crates/biome_js_type_info/src/format_type_info.rs (3)
crates/biome_js_type_info/src/resolver.rs (1)
  • ty (518-520)
crates/biome_js_type_info/src/type_data.rs (1)
  • ty (545-550)
crates/biome_module_graph/src/js_module_info/binding.rs (1)
  • ty (92-94)
crates/biome_js_type_info/src/helpers.rs (2)
crates/biome_js_type_info/src/resolver.rs (8)
  • ty (518-520)
  • from (322-324)
  • from (329-331)
  • from (401-406)
  • from (411-416)
  • id (68-70)
  • new (51-53)
  • new (290-295)
crates/biome_js_type_info/src/type_data.rs (15)
  • ty (545-550)
  • from (174-176)
  • from (180-182)
  • from (186-188)
  • from (192-194)
  • from (198-200)
  • from (204-206)
  • from (210-212)
  • from (216-218)
  • from (222-224)
  • from (228-230)
  • instance_of (295-297)
  • new (39-43)
  • new (1425-1429)
  • new (1460-1470)
crates/biome_js_type_info/src/type_data.rs (1)
crates/biome_js_type_info/src/resolver.rs (12)
  • from (322-324)
  • from (329-331)
  • from (401-406)
  • from (411-416)
  • new (51-53)
  • new (290-295)
  • index (73-75)
  • index (297-299)
  • resolver_id (103-105)
  • resolver_id (367-369)
  • is_index_signature_with_ty (482-486)
  • ty (518-520)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check Dependencies
🔇 Additional comments (14)
crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts (1)

1-9: LGTM! Well-crafted test case for index signature Promise handling.

This test effectively covers the scenario where a Promise-returning function is accessed via an index signature and not awaited, which should trigger the noFloatingPromises rule.

crates/biome_js_type_info/src/format_type_info.rs (1)

352-354: LGTM! Clean formatting for index signatures.

The square bracket notation [<ty>] is the standard way to represent index signatures in TypeScript, making this a good choice for formatting.

crates/biome_js_type_info/src/type_data.rs (4)

233-237: LGTM! Sensible From implementation for Tuple.


855-860: LGTM! Proper fallback to rest elements.

The method correctly handles tuple element access with a sensible fallback to the last element if it's a rest element.


863-877: Module ID propagation looks correct.

The slice_from method properly applies the resolver's module ID to each element's type reference, maintaining the resolver-aware pattern throughout.


934-939: LGTM! Clean predicate-based index signature checking.

crates/biome_js_type_info/src/flattening/expressions.rs (4)

122-130: LGTM! Clean refactor to use the new helper methods.

The destructuring logic is properly delegated to the new flattened_destructure function, and the index expression handling correctly uses the new find_element_type_at_index API with proper module ID handling.


261-264: LGTM! Proper use of the new finder API.


291-296: Good fallback to index signatures for property access.

The code correctly attempts to find a named member first, then falls back to string index signatures if no named member exists. This properly implements the TypeScript semantics for property access.


370-434: Comprehensive destructuring implementation.

The flattened_destructure function handles all destructuring cases thoroughly:

  • Array/tuple element access by index
  • Rest elements from a specific index
  • Object property access with index signature fallback
  • Class static member destructuring
  • Rest object patterns with exclusions

The implementation correctly applies module IDs throughout and properly resolves references.

crates/biome_js_type_info/src/helpers.rs (4)

47-68: LGTM! Clean element type extraction with proper optionality handling.

The method correctly handles both tuples and arrays, properly tracking optionality for rest elements and array indices.


71-81: LGTM! Convenient index signature finder.


331-346: Clean abstraction for optional element references.

The ElementTypeReference struct and its into_reference method provide a clean way to handle optional elements, properly registering them with the resolver when needed.


612-616: Naming consistency for type predicates.

The new predicates is_never_keyword, is_number, and is_string follow the existing naming pattern. Good consistency!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts (1)

9-9: Add bracket-notation coverage as a sibling test

To cover the string-index path explicitly, add a second test that uses obj["asyncFunc"]() (dot path is already covered here).

Would you like me to open a follow-up with a new file 03c_invalid_bracket.ts containing:

const obj: { [key: string]: () => Promise<string> } = { asyncFunc }
async function asyncFunc() { return Promise.resolve("foobar") }
obj["asyncFunc"]()
crates/biome_js_type_info/src/flattening/expressions.rs (1)

370-431: Destructuring: centralised lookups are good; consider DRY helper

The repeated pattern find_member(...).or_else(find_index_signature_with_ty(...string...)) shows up in multiple arms. Consider a tiny helper on ResolvedTypeData to fetch “named or string-indexed” members to keep this logic in one place.

Happy to draft it if you want.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba74fb0 and b52bf24.

⛔ Files ignored due to path filters (4)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_country_info.snap is excluded by !**/*.snap and included by **
  • crates/biome_module_graph/tests/snapshots/test_resolve_recursive_looking_vfile.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (12)
  • .changeset/infinite-indices-infer.md (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts (1 hunks)
  • crates/biome_js_type_info/src/flattening/expressions.rs (7 hunks)
  • crates/biome_js_type_info/src/format_type_info.rs (1 hunks)
  • crates/biome_js_type_info/src/helpers.rs (4 hunks)
  • crates/biome_js_type_info/src/local_inference.rs (1 hunks)
  • crates/biome_js_type_info/src/resolver.rs (1 hunks)
  • crates/biome_js_type_info/src/type.rs (2 hunks)
  • crates/biome_js_type_info/src/type_data.rs (6 hunks)
  • crates/biome_module_graph/tests/spec_tests.rs (4 hunks)
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • crates/biome_resolver/tests/fixtures/resolver_cases_3/tsconfig.json
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03_invalid.ts
  • .changeset/infinite-indices-infer.md
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/helpers.rs
🧰 Additional context used
📓 Path-based instructions (7)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
crates/biome_js_type_info/src/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

crates/biome_js_type_info/src/**/*.rs: Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format all Rust source files before committing (just f)

Files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
🧠 Learnings (10)
📚 Learning: 2025-09-05T09:13:58.901Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-05T09:13:58.901Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/nursery/** : Place snapshot test cases for new rules under tests/specs/nursery/<ruleName>/ with files prefixed by invalid/valid

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,biome_module_graph/src}/**/*.rs : When pattern-matching on ResolvedTypeData via as_raw_data(), ensure any nested TypeReferences are subsequently resolved using the correct ResolverId; never use the raw data with a resolver without applying the right ResolverId to avoid panics

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/{src,resolver,biome_module_graph/src}/**/*.rs : Implement and use type resolution via the TypeResolver trait; resolvers own TypeStore vectors and provide fast by-id and hashed lookups

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
PR: biomejs/biome#7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference may resolve qualifiers to local declarations or globals (TypeReference::Resolved), mark imported bindings as TypeReference::Import, and set unresolved to TypeReference::Unknown; it must not look beyond the current module

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/js_module_info/scoped_resolver.rs : Full inference resolves TypeReference::Import across modules into TypeReference::Resolved using the module graph; do not cache full-inference results

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/flattening.rs : Flatten types only after references are resolved; e.g., addition of two TypeData::Number flattens to TypeData::Number, otherwise often to TypeData::String

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/local_inference.rs : Local inference must not perform type resolution; it should only create TypeReference::Qualifier entries from syntax

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/flattening/expressions.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement

Applied to files:

  • crates/biome_js_type_info/src/flattening/expressions.rs
🧬 Code graph analysis (1)
crates/biome_js_type_info/src/type_data.rs (1)
crates/biome_js_type_info/src/resolver.rs (6)
  • index (73-75)
  • index (297-299)
  • resolver_id (103-105)
  • resolver_id (367-369)
  • is_index_signature_with_ty (482-486)
  • ty (518-520)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Documentation
  • GitHub Check: Test Node.js API
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
🔇 Additional comments (12)
crates/biome_js_analyze/tests/specs/nursery/noFloatingPromises/03b_invalid.ts (2)

1-3: Test setup looks good

Referencing asyncFunc before its declaration relies on hoisting, which is fine here and keeps the fixture minimal.


1-10: Verify test naming convention

Our learnings suggest prefixing files with valid/invalid. This suite uses numbered filenames. Please confirm which convention we’re standardising on and rename if needed.

crates/biome_js_type_info/src/flattening/expressions.rs (5)

125-130: Index access: resolver-aware element lookup LGTM

Using find_element_type_at_index(...).into_reference(resolver) is the right direction and avoids raw-data misuse.


261-265: Tuple static-member via Array fallback LGTM

Switch to array.find_member(... && !member.is_static()) is clearer than scanning all members manually.


292-297: String index-signature fallback: ensure literal-aware predicate

If is_string was renamed to is_string_or_string_literal (per PR context), update the predicate; otherwise this won’t match string literals.

Apply if applicable:

-                        .or_else(|| {
-                            object.find_index_signature_with_ty(resolver, |ty| ty.is_string())
-                        })?;
+                        .or_else(|| {
+                            object.find_index_signature_with_ty(resolver, |ty| ty.is_string_or_string_literal())
+                        })?;

349-353: Call-signature lookup refactor LGTM

Migrating to find_member(... is_call_signature()) for both InstanceOf and Interface/Object keeps call resolution consistent and avoids resolver-id footguns.

Also applies to: 358-362


385-395: Also update string-literal predicate in destructuring

Same potential rename as above; update the predicate if is_string_or_string_literal exists.

-                    .or_else(|| subject.find_index_signature_with_ty(resolver, |ty| ty.is_string()))
+                    .or_else(|| subject.find_index_signature_with_ty(resolver, |ty| ty.is_string_or_string_literal()))
-                .or_else(|| resolved.find_index_signature_with_ty(resolver, |ty| ty.is_string()))?;
+                .or_else(|| resolved.find_index_signature_with_ty(resolver, |ty| ty.is_string_or_string_literal()))?;

Also applies to: 421-423

crates/biome_js_type_info/src/type_data.rs (5)

233-237: From for TypeData LGTM

Nice ergonomic win; avoids boilerplate boxing at call sites.


855-861: Tuple.get_element: rest fallback LGTM

Returning the last rest element when out of bounds matches TS behaviour for variadic tails.


934-939: Index-signature predicate on TypeMember LGTM

Useful utility that pairs nicely with the resolver’s is_index_signature_with_ty.


863-877: slice_from invocations updated
Verified that the only occurrence in the repo (helpers.rs:111) passes self.resolver_id(); no legacy calls remain.


959-966: Approve IndexSignature member semantics

Exhaustive handling in has_name, name(), and is_static() now covers IndexSignature as intended.

@arendjr arendjr merged commit 98cf9af into main Sep 9, 2025
30 checks passed
@arendjr arendjr deleted the index-signatures branch September 9, 2025 20:38
@github-actions github-actions bot mentioned this pull request Sep 9, 2025
kedevked pushed a commit to kedevked/biome that referenced this pull request Sep 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter A-Project Area: project A-Resolver Area: resolver A-Type-Inference Area: type inference L-JavaScript Language: JavaScript and super languages

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

💅 noFloatingPromises rule fails on objects with index signature returning Promise

1 participant