Skip to content

@typescript-eslint/no-deprecated#491

Open
ScriptedAlchemy wants to merge 21 commits into
mainfrom
codex/ts-eslint-no-deprecated-92ca
Open

@typescript-eslint/no-deprecated#491
ScriptedAlchemy wants to merge 21 commits into
mainfrom
codex/ts-eslint-no-deprecated-92ca

Conversation

@ScriptedAlchemy
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings March 3, 2026 20:06
@ScriptedAlchemy ScriptedAlchemy changed the title feat(typescript): add no-deprecated rule @typescript-eslint/no-deprecated Mar 3, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new TypeScript linting rule, no-deprecated, which helps developers identify and avoid using deprecated code elements. The rule leverages TypeScript's type checking capabilities to detect declarations marked with @deprecated tags, providing warnings with optional deprecation reasons. This enhancement improves code quality by encouraging the use of up-to-date APIs. Additionally, a minor adjustment was made to the linter's core API to ensure all available rules are active by default if no explicit rule configuration is specified.

Highlights

  • New TypeScript Linting Rule: Implemented a new TypeScript linting rule, no-deprecated, to identify and report the usage of @deprecated declarations in code.
  • Rule Integration: Integrated the no-deprecated rule into the linter's global registry and configuration system.
  • Testing and Documentation: Added comprehensive unit tests and documentation for the new no-deprecated rule.
  • Default Rule Enabling: Adjusted the linter's API to ensure all rules are enabled by default when no specific rules are provided in the configuration.
Changelog
  • cmd/rslint/api.go
    • Modified rule initialization logic to ensure all rules are enabled by default if no rules are explicitly configured.
  • internal/config/config.go
    • Imported the new no_deprecated rule and registered it within the global rule registry for TypeScript.
  • internal/plugins/typescript/rules/no_deprecated/no_deprecated.go
    • Added the core implementation of the no-deprecated rule, including logic for detecting deprecated symbols, parsing JSDoc reasons, and handling various AST node types.
  • internal/plugins/typescript/rules/no_deprecated/no_deprecated.md
    • Created documentation detailing the purpose and usage of the no-deprecated rule.
  • internal/plugins/typescript/rules/no_deprecated/no_deprecated_test.go
    • Implemented unit tests for the no-deprecated rule, covering various scenarios of deprecated usage and configuration options.
  • packages/rslint-test-tools/rstest.config.mts
    • Enabled the test suite for the no-deprecated rule in the rslint test configuration.
  • packages/rslint-test-tools/tests/typescript-eslint/rules/snapshots/no-deprecated.test.ts.snap
    • Generated snapshot tests for the no-deprecated rule's diagnostic output.
  • packages/rslint-test-tools/tests/typescript-eslint/rules/no-deprecated.test.ts
    • Updated the rule tester setup to include noFormat and jsxLanguageOptions.
    • Added new test cases for the no-deprecated rule, including some skipped JSX-related tests.
Activity
  • The pull request was created by ScriptedAlchemy.
  • No human activity (comments, reviews, or progress updates) has been recorded yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the @typescript-eslint/no-deprecated rule, a substantial feature that includes the rule's implementation, documentation, and tests. The changes are well-structured. My review focuses on a couple of opportunities to improve code clarity and remove redundancy. Specifically, I've pointed out a duplicated code block in the API handler and a potential simplification in an AST traversal helper function. Overall, great work on adding this complex rule.

Comment thread cmd/rslint/api.go Outdated
Comment thread internal/plugins/typescript/rules/no_deprecated/no_deprecated.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for the @typescript-eslint/no-deprecated rule to the TypeScript plugin, including parity tests against the upstream typescript-eslint test suite and wiring the rule into the registry/test runner.

Changes:

  • Implement no-deprecated rule in Go (TypeScript plugin) with allow-list support and deprecation-reason extraction.
  • Add/enable TypeScript-eslint compatibility tests + snapshot for no-deprecated.
  • Register the rule in the global rule registry and adjust IPC lint defaults.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/rslint-test-tools/tests/typescript-eslint/rules/no-deprecated.test.ts Updates rule-tester cases (JSX languageOptions/noFormat) and skips a few React-type-dependent cases.
packages/rslint-test-tools/tests/typescript-eslint/rules/snapshots/no-deprecated.test.ts.snap Adds snapshot output for invalid cases for the new rule.
packages/rslint-test-tools/rstest.config.mts Enables the no-deprecated test in rstest config.
internal/plugins/typescript/rules/no_deprecated/no_deprecated.go New rule implementation for detecting deprecated symbol usage.
internal/plugins/typescript/rules/no_deprecated/no_deprecated_test.go Adds Go unit tests for allow-list import matching and basic rule behavior.
internal/plugins/typescript/rules/no_deprecated/no_deprecated.md Adds minimal rule documentation + upstream reference.
internal/config/config.go Registers @typescript-eslint/no-deprecated in the TypeScript-eslint plugin registry.
cmd/rslint/api.go Changes IPC lint behavior to default-enable all rules when none are specified (now redundantly implemented).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/rslint/api.go Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6364c5745

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/rslint/api.go Outdated
Comment thread internal/plugins/typescript/rules/no_deprecated/no_deprecated.go
@ScriptedAlchemy ScriptedAlchemy enabled auto-merge (squash) March 11, 2026 02:17
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Mar 12, 2026

Deploying rslint with  Cloudflare Pages  Cloudflare Pages

Latest commit: ad15bbe
Status: ✅  Deploy successful!
Preview URL: https://a3346a70.rslint.pages.dev
Branch Preview URL: https://codex-ts-eslint-no-deprecate.rslint.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@fansenze fansenze left a comment

Choose a reason for hiding this comment

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

Review of the no-deprecated port (P0/P1 findings). Several conclusions are backed by ablation/probe experiments, noted inline. Not blocking — happy to discuss.

return taggedTemplate != nil && taggedTemplate.Tag == node
}

func isDeprecatedNodeAssertFailOverload(ctx rule.RuleContext, node *ast.Node, name string) (bool, string) {
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.

These two helpers (isDeprecatedNodeAssertFailOverload here, isDeprecatedFsExistsImport at L1880) hard-code the API name, package, and the full deprecation reason string including version numbers.

I ablated both (forced return false) and reran the suite: import assert from 'node:assert'; assert.fail({}, {}) fails immediately — this case is supported only by the hard-coding (fs.exists is structurally identical). The same root cause appears elsewhere: the skipped <div aria-grabbed /> test also yields no diagnostic because the deprecation lives in lib.dom.d.ts. So @deprecated from an external .d.ts (lib / node_modules) isn't detected, and instead two specific APIs are patched in by hand — everything else from node_modules goes undetected. The root cause is worth fixing rather than per-API patching.

return found, reason
}

func deprecatedVariableInfoByNameInSource(ctx rule.RuleContext, name string) (bool, string) {
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.

This *ByNameInSource family walks the whole SourceFile and matches declarations by name string, detached from symbol resolution (used as a fallback in checkIdentifier, L2085).

This produces false positives when a local variable/parameter shadows a deprecated declaration of the same name — the reported identifier resolves to the shadowing symbol, which is not deprecated, yet gets flagged. Verified with two probes:

/** @deprecated */ const foo = 1;
function bar(foo: number) { return foo; }            // FALSE POSITIVE on `foo`
/** @deprecated */ const value = 1;
function bar() { const value = 2; return value; }    // FALSE POSITIVE on `value`

Detection should rely on the resolved symbol, not name matching.

// Skipped: React JSX deprecation requires React types (tsgolint parity)
{
code: `
skip: true,
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.

4 invalid JSX cases are skipped (here + L2956, L2971, L3000) with the note "requires React types". I removed the skips and ran each:

  • AProps (here), foo-bar:baz-bam (L2971), Tab.List (L3000) all PASS — the rule reports the deprecated prop with the correct messageId + line/column. Their @deprecated comes from local declarations (a plain interface), so "requires React types" doesn't apply; skipping them just drops working coverage.
  • Only const a = <div aria-grabbed /> (L2956) genuinely fails (no diagnostic) — the deprecation is in lib.dom.d.ts (external), same root cause as the hard-coded node_modules helpers.

Please un-skip the 3 that pass, and track the external-lib case (aria-grabbed) explicitly rather than skipping silently.

ctx.ReportRange(diagnosticRange, message)
}
if sourceFile != nil {
diagnostics := ctx.TypeChecker.GetSuggestionDiagnostics(context.Background(), sourceFile)
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.

Two parallel detection paths — GetSuggestionDiagnostics (here) + the hand-written AST listeners (L2155+) — deduped by text range via reportedRanges (L1996). By inspection (not reproduced) this looks fragile: if the two paths compute slightly different ranges, dedup fails and you get duplicate reports. There are also text-based heuristics: isInImportStatementRange (L1364) classifies "inside an import" by parsing the source line as text, and hasDeprecatedTagInSource (L205) scans characters backward for /**. Upstream is purely symbol/type driven; these heuristics are a smell.

Comment thread cmd/rslint/api.go
sourceFiles[filePath] = sourceFile
sourceFilesLock.Unlock()

if len(req.RuleOptions) == 0 {
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.

Unrelated infra changes, with an empty PR description:

  • This len(req.RuleOptions) == 0 branch changes global behavior (runs config-enabled rules instead of nothing when no options are passed).
  • RuleCount (L291) changes from "configured" to "executed".
  • RequiresTypeInfo (L259): by code reading this appears to be a no-op on the IPC path (no TypeInfoFiles is passed and IPC never calls FilterNonTypeAwareRules) — if it's actually needed, add a test; if not, drop it.

Please split infra changes into a separate PR and document them.


// Remove length bytes from buffer
this.chunks = [combined.slice(4)];
this.chunks = [combined.subarray(4)];
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.

Unrelated to the rule. On the Node side (node.ts) Buffer.slicesubarray is fine (slice is deprecated). But here combined is a Uint8Array: .slice() copies while .subarray() returns a shared view — different memory semantics on the IPC message boundary, with no test coverage. I haven't reproduced a concrete bug, but it's an aliasing risk worth isolating and justifying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants