🌐 AI搜索 & 代理 主页
Skip to content

Conversation

@nayounsang
Copy link
Contributor

@nayounsang nayounsang commented Jun 20, 2025

PR Checklist

Overview

Strict checks on exports with same type and variable name

  • If the name is the same, the variable is isTypeVariable && isValueVariable.
  • ClassName, TSEnumName, TSModuleName, ImportBinding and arguments also have same characteristics
  • Therefore, only the cases that correspond to the issue are properly verified.

Perform additional validating for abnormal cases

  • def.node.type !== AST_NODE_TYPES.TSTypeAliasDeclaration

Add test cases

  • tc mentioned in issue and similar but valid

@typescript-eslint
Copy link
Contributor

Thanks for the PR, @nayounsang!

typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community.

The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately.

Thanks again!


🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint.

@netlify
Copy link

netlify bot commented Jun 20, 2025

Deploy Preview for typescript-eslint ready!

Name Link
🔨 Latest commit fccdd43
🔍 Latest deploy log https://app.netlify.com/projects/typescript-eslint/deploys/6925a2ead324580008709597
😎 Deploy Preview https://deploy-preview-11322--typescript-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 91 (🔴 down 7 from production)
Accessibility: 97 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: 80 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@nayounsang nayounsang changed the title fix(eslint-plugin): [no-unused-vars] no is assigned a value but only used as a type error when it has a same name type alias declaration exporte fix(eslint-plugin): [no-unused-vars] no is assigned a value but only used as a type error when it has a same name Jun 20, 2025
@nx-cloud
Copy link

nx-cloud bot commented Jun 20, 2025

View your CI Pipeline Execution ↗ for commit a95d35e

Command Status Duration Result
nx test eslint-plugin --coverage=false ✅ Succeeded 5m 8s View ↗
nx run-many -t lint ✅ Succeeded 3m 14s View ↗
nx run-many -t typecheck ✅ Succeeded 2m 14s View ↗
nx run integration-tests:test ✅ Succeeded 6s View ↗
nx test eslint-plugin-internal --coverage=false ✅ Succeeded 3s View ↗
nx test typescript-estree --coverage=false ✅ Succeeded 2s View ↗
nx run types:build ✅ Succeeded 5s View ↗
nx run generate-configs ✅ Succeeded 8s View ↗
Additional runs (27) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2025-08-25 11:58:32 UTC

@codecov
Copy link

codecov bot commented Jun 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.88%. Comparing base (bd9e490) to head (a95d35e).
⚠️ Report is 162 commits behind head on main.

⚠️ Current head a95d35e differs from pull request most recent head fccdd43

Please upload reports for the commit fccdd43 to get more accurate results.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #11322   +/-   ##
=======================================
  Coverage   90.87%   90.88%           
=======================================
  Files         505      505           
  Lines       51146    51157   +11     
  Branches     8424     8429    +5     
=======================================
+ Hits        46480    46494   +14     
+ Misses       4652     4649    -3     
  Partials       14       14           
Flag Coverage Δ
unittest 90.88% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...s/eslint-plugin/src/util/collectUnusedVariables.ts 96.86% <100.00%> (+0.67%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nayounsang
Copy link
Contributor Author

Its a different issue:#8315, but we need to figure out if this is a workable solution.

@nayounsang
Copy link
Contributor Author

Its a different issue:#8315, but we need to figure out if this is a workable solution.

Ah, it is different. should change validate logic.
I think I need to work on another PR. If this PR is headed in the right direction.

@JoshuaKGoldberg
Copy link
Member

I think I need to work on another PR. If this PR is headed in the right direction.

@nayounsang apologies, I'm not following - are you suggesting we should or shouldn't review this PR?

@nayounsang
Copy link
Contributor Author

@JoshuaKGoldberg
Oh, please review this PR. I'm ready.

The comments are my own monologue. I tend to take notes of everything and I just saw another issue that seemed related to this PR. After looking into it, it seems that even if this PR is resolved, there will be additional work needed to resolve the other issues.

Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

🙌 Looks like a good start! I didn't review deeply because the .every line looks like it's either unnecessary or not fully tested. Which makes me suspect things might change up a bit. Could you please take a look?

@JoshuaKGoldberg JoshuaKGoldberg added the awaiting response Issues waiting for a reply from the OP or another party label Jun 30, 2025
@github-actions github-actions bot removed the awaiting response Issues waiting for a reply from the OP or another party label Jul 12, 2025
Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

this is almost there -- but it misses this case:

const A = 0;
export interface A {}

Comment on lines 424 to 433
function isMergedTypeDeclaration(
variable: Variable,
node: TSESTree.Node,
): boolean {
return (
node.type === AST_NODE_TYPES.TSTypeAliasDeclaration &&
variable.isTypeVariable &&
variable.isValueVariable
);
}
Copy link
Member

Choose a reason for hiding this comment

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

A better implementation to catch the interface case would leverage variable.defs:

function isMergedTypeDeclaration(
  variable: Variable,
): boolean {
  return (
    variable.defs.length > 1 &&
    variable.isValueVariable &&
    variable.isTypeVariable &&
    variable.defs.some(d => d.type === DefinitionType.Type)
  );
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can't cover this case:

// valid, but report
export const Foo = 0;
export type Foo = typeof Foo;

export const Foo = 0;
export interface Foo {}

What I meant was to check for the export type Foo = ... statement. But in this case, it returns true if there are other type declarations besides the export statement. This is because node exists within the export statement when the isMergedTypeDeclaration is called.

So I've taken a different approach, can you please tell me if I'm going in the right direction?

@bradzacher bradzacher added the awaiting response Issues waiting for a reply from the OP or another party label Aug 16, 2025
@nayounsang nayounsang changed the title fix(eslint-plugin): [no-unused-vars] no is assigned a value but only used as a type error when it has a same name fix(eslint-plugin): [no-unused-vars] no is assigned a value but only used as a type error when it has a same name in export statement Aug 17, 2025
@nayounsang nayounsang requested a review from bradzacher August 17, 2025 13:47
@github-actions github-actions bot removed the awaiting response Issues waiting for a reply from the OP or another party label Aug 17, 2025
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

LGTM, thanks! I'll defer to @bradzacher as well on review. 👍

@JoshuaKGoldberg JoshuaKGoldberg added the 1 approval >=1 team member has approved this PR; we're now leaving it open for more reviews before we merge label Sep 15, 2025
Copy link
Member

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

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

There are the following 4 classes of cases here and we need to make sure we're reporting correctly on all of them.

///
/// case 1 -- both exported -- expected no reports
///

export interface Foo1 { }
export const Foo1 = 0;

export type Bar1 = 0;
export const Bar1 = 0;


export const Foo2 = 0;
export interface Foo2 { }

export const Bar2 = 0;
export type Bar2 = 0;

///
/// case 2 -- both exported via named export -- expected no reports
///

interface Foo7 { }
const Foo7 = 0;
export { Foo7 };

type Bar7 = 0;
const Bar7 = 0;
export { Bar7 };


const Foo8 = 0;
interface Foo8 { }
export { Foo8 };

const Bar8 = 0;
type Bar8 = 0;
export { Bar8 };

///
/// case 3 -- just value exported -- expected type is reported
///

interface Foo3 { }
export const Foo3 = 0;

type Bar3 = 0;
export const Bar3 = 0;



export const Foo4 = 0;
interface Foo4 { }

export const Bar4 = 0;
type Bar4 = 0;

///
/// case 4 -- just type exported -- expected value is reported
///

export interface Foo5 { }
const Foo5 = 0;

export type Bar5 = 0;
const Bar5 = 0;



const Foo6 = 0;
export interface Foo6 { }

const Bar6 = 0;
export type Bar6 = 0;

The current implementation reports nothing on this code (which is technically half right heh).

Your current implementation:

  • does not report on case 1 -- ✔️
  • does not report on case 2 -- ✔️
  • does not report on case 3 -- ❌
  • reports on case 4 -- ✔️

PR branch playground

So we'll need to handle this and add test cases

@bradzacher bradzacher added awaiting response Issues waiting for a reply from the OP or another party and removed 1 approval >=1 team member has approved this PR; we're now leaving it open for more reviews before we merge labels Oct 7, 2025
@nayounsang
Copy link
Contributor Author

nayounsang commented Oct 24, 2025

Hi. @bradzacher, There are some valid test cases I don't understand among the ones wrote before.
This is same with case 3 -- just value exported -- expected type is reported on your comment.

    `
interface Foo {
  bar: string;
}
export const Foo = 'bar';
    `,
    `
export const Foo = 'bar';
interface Foo {
  bar: string;
}
    `,

This is added from #6873
This is a PR that check all the declarations not just the first declaration.
At the time, the review seemed to have determined that the test case was not problematic. So I understood this to be an intended behavior.(In my personal opinion, a report is needed.) What do you think?
+cc @JoshuaKGoldberg

@bradzacher
Copy link
Member

@nayounsang the test cases may have been added in the past, but that doesn't mean they're right! They were right in so far as they allowed the rule to understand when a multi-declaration variable was exported in its second declaration, but the result is wrong.

interface Foo {
//        ^^^ Type Foo is unused
  bar: string;
}
export const Foo = 'bar';
export const Foo = 'bar';
interface Foo {
//        ^^^ Type Foo is unused
  bar: string;
}

This is what we should expect to report for these two cases -- we should be able to understand that the variable's second declaration is unused.

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

Labels

awaiting response Issues waiting for a reply from the OP or another party

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: [no-unused-vars] no is assigned a value but only used as a type error when it has a same name type alias declaration exported

3 participants