Skip to content

feat(type-info): preserve object-literal as const properties#10143

Merged
ematipico merged 2 commits into
biomejs:mainfrom
minseong0324:fix/no-misleading-return-type-as-const
May 4, 2026
Merged

feat(type-info): preserve object-literal as const properties#10143
ematipico merged 2 commits into
biomejs:mainfrom
minseong0324:fix/no-misleading-return-type-as-const

Conversation

@minseong0324

@minseong0324 minseong0324 commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

This PR was implemented with AI assistance from Codex.

Summary

Addresses the property-level as const case from #9810.

biome_js_type_info now preserves const-assertion information for object-literal members such as { a: "x" as const }, so type-aware rules can distinguish const-asserted properties from widened object properties without adding ad-hoc AST checks in individual rules.

Test Plan

Snapshot tests.

@changeset-bot

changeset-bot Bot commented Apr 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a53dd5c

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-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Type-Inference Area: type inference labels Apr 28, 2026
@codspeed-hq

codspeed-hq Bot commented Apr 28, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 62 untouched benchmarks
⏩ 192 skipped benchmarks1


Comparing minseong0324:fix/no-misleading-return-type-as-const (a53dd5c) with main (ac30057)2

Open in CodSpeed

Footnotes

  1. 192 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (1a2d354) during the generation of this report, so ac30057 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch 9 times, most recently from 7a73eca to 140108a Compare May 2, 2026 11:45
@github-actions github-actions Bot added the A-Project Area: project label May 2, 2026
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch 2 times, most recently from 316bcb1 to 7a73eca Compare May 2, 2026 13:00
@github-actions github-actions Bot removed the A-Project Area: project label May 2, 2026
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch from 7a73eca to 56ecfb5 Compare May 2, 2026 18:28
@github-actions github-actions Bot added the A-Project Area: project label May 2, 2026
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch 2 times, most recently from b33744a to 8a7fca9 Compare May 2, 2026 20:25
@github-actions github-actions Bot removed the A-Project Area: project label May 2, 2026
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch from 8a7fca9 to 40695da Compare May 3, 2026 04:52
@github-actions github-actions Bot added the A-Project Area: project label May 3, 2026
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch 5 times, most recently from f31b398 to ff66e86 Compare May 3, 2026 11:19
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch 2 times, most recently from 27bb933 to e43d8d6 Compare May 3, 2026 11:31
@minseong0324 minseong0324 force-pushed the fix/no-misleading-return-type-as-const branch from e43d8d6 to a53dd5c Compare May 3, 2026 11:51
@minseong0324 minseong0324 marked this pull request as ready for review May 3, 2026 12:11
@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR extends Biome's type system to recognise and properly handle TypeScript as const assertions on object literal properties. It introduces new TypeMemberKind variants for const-asserted members, updates type inference to deeply apply const assertions, and modifies several lint rules (noMisleadingReturnType, noUselessTypeConversion, useExhaustiveSwitchCases, useStringStartsEndsWith) to account for const-asserted property types when generating diagnostics.

Possibly related PRs

Suggested labels

A-Parser

Suggested reviewers

  • ematipico
  • dyc3
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly relates to the changeset, addressing property-level as const handling and type-inference improvements across multiple lint rules.
Title check ✅ Passed The title accurately reflects the main changes: preserving and inferring types for object-literal properties initialised with as const, enabling multiple lint rules to detect property-level type issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_js_analyze/src/lint/nursery/no_misleading_return_type.rs`:
- Around line 1497-1501: The predicate function
type_member_affects_instance_shape no longer excludes constructor members after
refactor; update the condition in type_member_affects_instance_shape to also
check && !member.is_constructor() so constructors return false (preserving the
original match semantics); locate the function
type_member_affects_instance_shape and add the is_constructor() exclusion
alongside the existing is_static(), is_getter(), and is_index_signature_with_ty
checks.

In `@crates/biome_js_type_info/src/local_inference.rs`:
- Around line 599-624: The current handlers for AnyJsExpression::TsAsExpression
and ::TsTypeAssertionExpression return Self::unknown() for all non-const
assertions, losing inner expression types; instead, after extracting
Ok(annotation) and Ok(inner), check is_const_reference_type(&annotation) as you
do now, but in the else branch call the normal expression resolver on the inner
expression (e.g. invoke the same resolution used for other expressions, passing
resolver and scope_id to resolve the inner) so that non-const assertions return
the inner expression's TypeData rather than Self::unknown(); keep using
type_data_from_const_assertion_expression(...) only for const assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6c54ee35-0738-44a3-a8d8-d303f0653485

📥 Commits

Reviewing files that changed from the base of the PR and between ac30057 and a53dd5c.

⛔ Files ignored due to path filters (5)
  • crates/biome_js_analyze/tests/specs/nursery/noMisleadingReturnType/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noMisleadingReturnType/valid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useExhaustiveSwitchCases/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useStringStartsEndsWith/invalidIndex.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (17)
  • .changeset/no-misleading-return-type-as-const-property.md
  • .changeset/no-useless-type-conversion-as-const-property.md
  • .changeset/use-exhaustive-switch-cases-as-const-property.md
  • .changeset/use-string-starts-ends-with-as-const-property.md
  • crates/biome_js_analyze/src/lint/nursery/no_misleading_return_type.rs
  • crates/biome_js_analyze/tests/specs/nursery/noMisleadingReturnType/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noMisleadingReturnType/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/useExhaustiveSwitchCases/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/useStringStartsEndsWith/invalidIndex.ts
  • crates/biome_js_type_info/src/flattening/intersections.rs
  • crates/biome_js_type_info/src/format_type_info.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/resolver.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/tests/local_inference.rs
  • crates/biome_module_graph/tests/spec_tests.rs

Comment on lines +599 to +624
AnyJsExpression::TsAsExpression(expr) => {
let Ok(annotation) = expr.ty() else {
return Self::unknown();
};
let Ok(inner) = expr.expression() else {
return Self::unknown();
};
if is_const_reference_type(&annotation) {
type_data_from_const_assertion_expression(resolver, scope_id, &inner)
} else {
Self::unknown()
}
}
AnyJsExpression::TsTypeAssertionExpression(expr) => {
let Ok(annotation) = expr.ty() else {
return Self::unknown();
};
let Ok(inner) = expr.expression() else {
return Self::unknown();
};
if is_const_reference_type(&annotation) {
type_data_from_const_assertion_expression(resolver, scope_id, &inner)
} else {
Self::unknown()
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd crates/biome_js_type_info/src && wc -l local_inference.rs

Repository: biomejs/biome

Length of output: 81


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '550,650p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 5604


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -n "TsSatisfiesExpression|TsNonNullAssertionExpression" local_inference.rs

Repository: biomejs/biome

Length of output: 210


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -n "from_any_js_expression" local_inference.rs | head -5

Repository: biomejs/biome

Length of output: 466


🏁 Script executed:

cd crates/biome_js_type_info/src && ast-grep --pattern 'fn from_any_js_expression($_) {
  $$$
}'

Repository: biomejs/biome

Length of output: 39


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '2500,2550p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 2144


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '430,500p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 4092


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -B5 -A5 "TsNonNullAssertionExpression|TsSatisfiesExpression" local_inference.rs | head -40

Repository: biomejs/biome

Length of output: 603


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '575,630p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 2985


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -n "TsNonNullAssertionExpression|TsSatisfiesExpression" local_inference.rs

Repository: biomejs/biome

Length of output: 210


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '430,700p' local_inference.rs | grep -A2 "AnyJsExpression::" | grep -E "TsNonNull|TsSatisfies|TsAs|TsType"

Repository: biomejs/biome

Length of output: 178


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '2515,2545p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 1428


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -B10 -A10 "is_const_reference_type" local_inference.rs | head -50

Repository: biomejs/biome

Length of output: 1950


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -A20 "fn is_const_reference_type" local_inference.rs

Repository: biomejs/biome

Length of output: 939


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -B5 -A15 "type_data_from_const_assertion_expression" local_inference.rs | head -60

Repository: biomejs/biome

Length of output: 2183


🏁 Script executed:

cd crates/biome_js_type_info && git log --oneline -20 | head -20

Repository: biomejs/biome

Length of output: 88


🏁 Script executed:

cd crates/biome_js_type_info/src && sed -n '2869,2950p' local_inference.rs | cat -n

Repository: biomejs/biome

Length of output: 3725


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -A30 "fn type_data_from_const_assertion_expression" local_inference.rs

Repository: biomejs/biome

Length of output: 1320


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -n "from_any_js_expression" local_inference.rs | grep "fn " | head -1

Repository: biomejs/biome

Length of output: 96


🏁 Script executed:

cd crates/biome_js_type_info && git log --all --oneline --grep="type.*assertion\|assertion.*expression" | head -10

Repository: biomejs/biome

Length of output: 39


🏁 Script executed:

cd crates/biome_js_type_info && git show HEAD:src/local_inference.rs 2>/dev/null | sed -n '599,624p' | head -30

Repository: biomejs/biome

Length of output: 39


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -B5 "TODO: Much" local_inference.rs

Repository: biomejs/biome

Length of output: 265


🏁 Script executed:

cd crates/biome_js_type_info/src && rg -C8 "TsAsExpression\|TsTypeAssertionExpression" local_inference.rs | grep -A10 -B10 "from_any_js_expression" | head -40

Repository: biomejs/biome

Length of output: 39


🏁 Script executed:

cd crates/biome_js_type_info && find . -name "*.rs" -path "*/tests/*" -exec grep -l "TsAsExpression\|TsTypeAssertionExpression\|TsSatisfiesExpression" {} \;

Repository: biomejs/biome

Length of output: 39


Preserve the inner expression type for non-const TypeScript assertion wrappers.

The code currently returns TypeData::unknown() for all assertions that aren't as const or <const>. This means expr as Foo, <Foo>expr, expr satisfies Bar, and expr! all lose type information. For non-const assertions, unwrap and resolve the inner expression instead—the assertion itself won't affect type inference, but discarding it altogether defeats the purpose of this improvement.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_type_info/src/local_inference.rs` around lines 599 - 624, The
current handlers for AnyJsExpression::TsAsExpression and
::TsTypeAssertionExpression return Self::unknown() for all non-const assertions,
losing inner expression types; instead, after extracting Ok(annotation) and
Ok(inner), check is_const_reference_type(&annotation) as you do now, but in the
else branch call the normal expression resolver on the inner expression (e.g.
invoke the same resolution used for other expressions, passing resolver and
scope_id to resolve the inner) so that non-const assertions return the inner
expression's TypeData rather than Self::unknown(); keep using
type_data_from_const_assertion_expression(...) only for const assertions.

@minseong0324 minseong0324 marked this pull request as draft May 3, 2026 12:50
@minseong0324 minseong0324 reopened this May 3, 2026
@minseong0324 minseong0324 marked this pull request as ready for review May 3, 2026 12:52
@minseong0324 minseong0324 changed the title feat(type-info): infer types through TypeScript assertion wrappers feat(type-info): preserve object-literal as const properties May 3, 2026
@minseong0324 minseong0324 marked this pull request as draft May 3, 2026 13:03
@minseong0324 minseong0324 marked this pull request as ready for review May 3, 2026 13:03

@ematipico ematipico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome work

@ematipico ematipico merged commit 56798a7 into biomejs:main May 4, 2026
45 checks passed
@github-actions github-actions Bot mentioned this pull request May 4, 2026
OIRNOIR pushed a commit to OIRNOIR/YouTube-Helper-Server that referenced this pull request May 12, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) |

---

### Release Notes

<details>
<summary>biomejs/biome (@&#8203;biomejs/biome)</summary>

### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@&#8203;biomejs/biome/CHANGELOG.md#2415)

[Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15)

##### Patch Changes

- [#&#8203;9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about.

- [#&#8203;10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`.

  For example, the following snippet triggers the rule:

  ```js
  import { nextTick } from "vue";

  nextTick(() => {
    updateDom();
  });
  ```

- [#&#8203;10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives.

  For example, the following snippet triggers the rule:

  ```vue
  <input @&#8203;keyup.13="submit" />
  ```

- [#&#8203;10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables.

- [#&#8203;10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available.

- [#&#8203;10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@&#8203;realknove](https://github.com/realknove)! - Fixed [#&#8203;10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers.

- [#&#8203;9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed [#&#8203;9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is.

- [#&#8203;10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed [#&#8203;10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group.

  The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group.

  ```json
  {
    "assist": {
      "actions": {
        "source": {
          "organizeImports": { "options": { "groups": [":INEXISTENT:"] } }
        }
      }
    }
  }
  ```

- [#&#8203;10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`).

  These functions are now reported because `null` and `number` are included in the return annotations but never returned:

  ```ts
  function getUser(): string | null {
    return "hello";
  } // null is never returned
  function getCode(): string | number {
    return "hello";
  } // number is never returned
  ```

- [#&#8203;10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line.

- [#&#8203;10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@&#8203;solithcy](https://github.com/solithcy)! - Fixed [#&#8203;10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement`

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`.

  This function is now reported because the return annotation widens a property initialized with `as const`:

  ```ts
  function f(): { value: string } {
    return { value: "text" as const };
  }
  ```

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`.

  This conversion is now reported because `message.value` is inferred as a string literal:

  ```ts
  const message = { value: "text" as const };
  String(message.value);
  ```

- [#&#8203;9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`.

  The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options.

  **Invalid**:

  ```js
  class Foo {
    bar() {
      // does not use `this`, invalid
      console.log("Hello Biome");
    }
  }
  ```

- [#&#8203;10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated.

- [#&#8203;10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts.

- [#&#8203;9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option.

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`.

  This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it:

  ```ts
  const status = { kind: "ready" as const };
  switch (status.kind) {
  }
  ```

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`.

  This comparison is now reported because `message.value` is inferred as a string literal:

  ```ts
  const message = { value: "hello" as const };
  message.value[0] === "h";
  ```

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/12
OIRNOIR pushed a commit to OIRNOIR/YouTube-Helper-Client that referenced this pull request May 13, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) |

---

### Release Notes

<details>
<summary>biomejs/biome (@&#8203;biomejs/biome)</summary>

### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@&#8203;biomejs/biome/CHANGELOG.md#2415)

[Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15)

##### Patch Changes

- [#&#8203;9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about.

- [#&#8203;10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`.

  For example, the following snippet triggers the rule:

  ```js
  import { nextTick } from "vue";

  nextTick(() => {
    updateDom();
  });
  ```

- [#&#8203;10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives.

  For example, the following snippet triggers the rule:

  ```vue
  <input @&#8203;keyup.13="submit" />
  ```

- [#&#8203;10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables.

- [#&#8203;10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available.

- [#&#8203;10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@&#8203;realknove](https://github.com/realknove)! - Fixed [#&#8203;10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers.

- [#&#8203;9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed [#&#8203;9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is.

- [#&#8203;10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed [#&#8203;10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group.

  The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group.

  ```json
  {
    "assist": {
      "actions": {
        "source": {
          "organizeImports": { "options": { "groups": [":INEXISTENT:"] } }
        }
      }
    }
  }
  ```

- [#&#8203;10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`).

  These functions are now reported because `null` and `number` are included in the return annotations but never returned:

  ```ts
  function getUser(): string | null {
    return "hello";
  } // null is never returned
  function getCode(): string | number {
    return "hello";
  } // number is never returned
  ```

- [#&#8203;10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line.

- [#&#8203;10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@&#8203;solithcy](https://github.com/solithcy)! - Fixed [#&#8203;10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement`

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`.

  This function is now reported because the return annotation widens a property initialized with `as const`:

  ```ts
  function f(): { value: string } {
    return { value: "text" as const };
  }
  ```

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`.

  This conversion is now reported because `message.value` is inferred as a string literal:

  ```ts
  const message = { value: "text" as const };
  String(message.value);
  ```

- [#&#8203;9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`.

  The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options.

  **Invalid**:

  ```js
  class Foo {
    bar() {
      // does not use `this`, invalid
      console.log("Hello Biome");
    }
  }
  ```

- [#&#8203;10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated.

- [#&#8203;10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts.

- [#&#8203;9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option.

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`.

  This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it:

  ```ts
  const status = { kind: "ready" as const };
  switch (status.kind) {
  }
  ```

- [#&#8203;10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`.

  This comparison is now reported because `message.value` is inferred as a string literal:

  ```ts
  const message = { value: "hello" as const };
  message.value[0] === "h";
  ```

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Client/pulls/3
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-Type-Inference Area: type inference L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants