Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(eslint-plugin): [no-invalid-void-type] don't flag function overloading withvoid in return type annotation#10422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

ronami
Copy link
Member

@ronamironami commentedNov 29, 2024
edited
Loading

PR Checklist

Overview

This PR addresses#5752 and adjusts the rule so it doesn't report onvoid that's used as part of the return type of a function overload implementation:

functionf():void;functionf(x:string):string;functionf(x?:string):void|string{if(x!==undefined){returnx;}}

tommie reacted with heart emoji
@typescript-eslint
Copy link
Contributor

Thanks for the PR,@ronami!

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 onhttps://opencollective.com/typescript-eslint.

@netlifyNetlify
Copy link

netlifybot commentedNov 29, 2024
edited
Loading

Deploy Preview fortypescript-eslint ready!

NameLink
🔨 Latest commit7887cc9
🔍 Latest deploy loghttps://app.netlify.com/sites/typescript-eslint/deploys/679fadc5f106910007f706b8
😎 Deploy Previewhttps://deploy-preview-10422--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: 92 (🔴 down 6 from production)
Accessibility: 100 (no change from production)
Best Practices: 92 (no change from production)
SEO: 98 (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 yourNetlify site configuration.

@nx-cloudNx Cloud
Copy link

nx-cloudbot commentedNov 29, 2024
edited
Loading

View yourCI Pipeline Execution ↗ for commit7887cc9.

CommandStatusDurationResult
nx test eslint-plugin --coverage=false✅ Succeeded7m 27sView ↗
nx test eslint-plugin✅ Succeeded5m 57sView ↗
nx test visitor-keys✅ Succeeded<1sView ↗
nx test visitor-keys --coverage=false✅ Succeeded<1sView ↗
nx run types:build✅ Succeeded<1sView ↗
nx run-many --target=build --exclude website --...✅ Succeeded24sView ↗
nx test type-utils✅ Succeeded<1sView ↗
nx test utils✅ Succeeded<1sView ↗
Additional runs (24)✅ Succeeded...View ↗

☁️Nx Cloud last updated this comment at2025-02-02 17:54:57 UTC

@codecovCodecov
Copy link

codecovbot commentedNov 29, 2024
edited
Loading

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.30%. Comparing base(1c73754) to head(7887cc9).
Report is 65 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@##             main   #10422      +/-   ##==========================================+ Coverage   87.26%   87.30%   +0.03%==========================================  Files         450      451       +1       Lines       15715    15750      +35       Branches     4601     4615      +14     ==========================================+ Hits        13714    13750      +36  Misses       1645     1645+ Partials      356      355       -1
FlagCoverage Δ
unittest87.30% <100.00%> (+0.03%)⬆️

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

Files with missing linesCoverage Δ
...es/eslint-plugin/src/rules/no-invalid-void-type.ts100.00% <100.00%> (+2.17%)⬆️
...es/eslint-plugin/src/util/hasOverloadSignatures.ts100.00% <100.00%> (ø)

... and1 file with indirect coverage changes

@ronamironami marked this pull request as ready for reviewNovember 30, 2024 13:43
Comment on lines 191 to 192
/* istanbul ignore next */
return [];
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Is there a preferred way to tackle this? I think this is currently an unreachable line.

Choose a reason for hiding this comment

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

#10388 - either it's reachable or it's not.

If it's not actually reachable then I'd say use type assertion(s) to tell TypeScript why it's wrong.

There might be opportunities to suggest improvements to AST types too. Example: thegetMembers(node.parent.parent) later on has the provided type asTSESTree.Node. But maybe somewhere in there a type could be made more specific? IsTSESTree.ExportDefaultDeclaration's.parent always aTSESTree.BlockStatement | TSESTree.Program, rather than the catch-allTSESTree.Node?

ronami reacted with thumbs up emoji
Copy link
MemberAuthor

@ronamironamiDec 19, 2024
edited
Loading

Choose a reason for hiding this comment

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

Interesting! I didn't consider proposing changes/improvements to the AST types. I've found#9560, and I think it would be a good option if I could be sure the changes are correct.

To my understanding, TypeScript's AST doesn't even have an actual AST node forExportDefaultDeclaration orExportNamedDeclaration as they're expressed asmodifiers.

I've looked into@babel/parser,@swc/types, and@oxc-project/types (also the more technical1,2), but I didn't find anything that makes me confident this is valid in every case. I did verify@typescript-eslint itself is type-checked successfully with these assumptions.

The stricter parent types for the AST I'd like to propose:

  • ExportDefaultDeclaration andExportNamedDeclaration should have the stricterparent type ofTSESTree.BlockStatement | TSESTree.Program | TSESTree. TSModuleBlock (I'm not sure ifTSESTree.BlockStatement is an option).

  • FunctionDeclaration should have the stricterparent type ofTSESTree.BlockStatement | TSESTree.ExportDefaultDeclaration | TSESTree.ExportNamedDeclaration | TSESTree.Program.

    TypeScript itself doesn't have a specificparent forFunctionDeclaration (it falls back to the genericts.Node), although they do have stricter parent types for some other nodes.

How did we verify the correctness of the proposals in#6225? Also, would this type of change be considered a breaking change? I noticed that#9560 was released in v8, but it wasn't marked as abreaking change.

I'm a bit hesitant to change the AST's types, as it can potentially lead to bugs, and I would love to hear opinions on this.

I updated the PR with these changes, so it's easier to discuss them.

Choose a reason for hiding this comment

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

The stricter parent types for the AST I'd like to propose:

I'd say those proposals should be a separate issue. I'm generally in favor of stricter parent types in general but we should discuss.

So I think how to handle that in this PR is up to you. Maybe either:

  • Link to the issue with anas
  • Draft this PR and mark it blocked till that's resolved

How did we verify the correctness of the proposals in#6225?

Other thanyarn build andyarn typecheck, pretty much just manual knowledge and testing.

breaking change?

I don't think improving the types of the AST to better reflect reality is breaking. In that sense it's a "feature".

Changing theruntime value would IMO be a breaking change.

ronami reacted with thumbs up emoji
Copy link
MemberAuthor

@ronamironamiJan 19, 2025
edited
Loading

Choose a reason for hiding this comment

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

That sounds good; I'm not sure why I mixed both on the same PR; thanks! 👍

I've opened#10682, drafted this PR, and marked it as blocked.

If the issue is accepted, I'll create a new PR with the stricter parent node changes and eventually re-open this PR for review with only the relevant changes.

Comment on lines 227 to 232
const id = nullThrows(
node.id,
'This may be null if and only if the parent is an `ExportDefaultDeclaration`.',
);

return id.name;
Copy link
MemberAuthor

@ronamironamiNov 30, 2024
edited
Loading

Choose a reason for hiding this comment

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

Thiscurrently only gets called for nodes whose parents aren'tExportDefaultDeclaration, and so this can never benull. If this code gets refactored, it may change, and this can throw.

I can change this to a chain-expression, though this will show up as a partially covered line by codecov.

Suggested change
constid=nullThrows(
node.id,
'This may be null if and only if the parent is an `ExportDefaultDeclaration`.',
);
returnid.name;
returnnode.id?.name;

Choose a reason for hiding this comment

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

Similar to the other comment, my fallback would be to use a! with a disable comment explaining why the types are wrong. If possible, fixing up the types to be correct would be even better.

You might find the existing uses of theMakeRequired utils type interesting. Some places in code use for node types in similar situations. E.g.no-confusing-void-expression has handling for return statements that must have anargument. Maybe there's a similar flow here for functions that must have anid?

I'm not worried about refactors. Our test coverage is so high that the cost of unnecessary safety precautions in code is IMO higher than the cost of the brittleness.

ronami reacted with thumbs up emoji
Copy link
MemberAuthor

@ronamironamiDec 19, 2024
edited
Loading

Choose a reason for hiding this comment

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

I'm confident the only possibility ofnode.id beingnull (forFunctionDeclaration orTSDeclareFunction) is in cases where the parent node is anExportDefaultDeclaration (also according to JavaScript's spec):

/**
* The function's name.
* - For an `ArrowFunctionExpression` this is always `null`.
* - For a `FunctionExpression` this may be `null` if the name is omitted.
* - For a `FunctionDeclaration` or `TSDeclareFunction` this may be `null` if
* and only if the parent is an `ExportDefaultDeclaration`.
*/
id:Identifier|null;

I think that updating the types to be stricter here would be more challenging. I've resorted to using a! with a disable comment and explaining why this is necessary.

JoshuaKGoldberg reacted with thumbs up emoji
Copy link
Member

@JoshuaKGoldbergJoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

LGTM overall! Just requesting touchups around the types /istanbul ignores. 🚀

ronami reacted with thumbs up emoji
Comment on lines 191 to 192
/* istanbul ignore next */
return [];

Choose a reason for hiding this comment

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

#10388 - either it's reachable or it's not.

If it's not actually reachable then I'd say use type assertion(s) to tell TypeScript why it's wrong.

There might be opportunities to suggest improvements to AST types too. Example: thegetMembers(node.parent.parent) later on has the provided type asTSESTree.Node. But maybe somewhere in there a type could be made more specific? IsTSESTree.ExportDefaultDeclaration's.parent always aTSESTree.BlockStatement | TSESTree.Program, rather than the catch-allTSESTree.Node?

ronami reacted with thumbs up emoji
Comment on lines 227 to 232
const id = nullThrows(
node.id,
'This may be null if and only if the parent is an `ExportDefaultDeclaration`.',
);

return id.name;

Choose a reason for hiding this comment

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

Similar to the other comment, my fallback would be to use a! with a disable comment explaining why the types are wrong. If possible, fixing up the types to be correct would be even better.

You might find the existing uses of theMakeRequired utils type interesting. Some places in code use for node types in similar situations. E.g.no-confusing-void-expression has handling for return statements that must have anargument. Maybe there's a similar flow here for functions that must have anid?

I'm not worried about refactors. Our test coverage is so high that the cost of unnecessary safety precautions in code is IMO higher than the cost of the brittleness.

ronami reacted with thumbs up emoji
@JoshuaKGoldbergJoshuaKGoldberg added the awaiting responseIssues waiting for a reply from the OP or another party labelDec 14, 2024
Comment on lines +582 to +591
{
code: 'type invalidVoidUnion = void | Map;',
errors: [
{
column: 25,
line: 1,
messageId: 'invalidVoidUnionConstituent',
},
],
},
Copy link
MemberAuthor

@ronamironamiDec 19, 2024
edited
Loading

Choose a reason for hiding this comment

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

This test is unrelated to the PR, but it adds coverage to part of the code that is currently uncovered (it seemed small enough to be part of the PR, even if it's unrelated).

Please let me know if I should revert this part.

JoshuaKGoldberg reacted with thumbs up emoji
@github-actionsgithub-actionsbot removed the awaiting responseIssues waiting for a reply from the OP or another party labelDec 19, 2024
return getStaticMemberAccessValue(node, context);
}

function hasOverloadMethods(
Copy link
MemberAuthor

@ronamironamiDec 20, 2024
edited
Loading

Choose a reason for hiding this comment

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

I think this may be useful as a shared utility function for different rules. Re-using this function (pretty much as is) simplifies tackling#4586 (which I'll be happy to push a PR for), for example.

JoshuaKGoldberg reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Adding that this attempts to emulatechecker.isImplementationOfOverload() for rules which aren't type-aware.

JoshuaKGoldberg reacted with thumbs up emoji
tommie added a commit to tommie/stm-ts that referenced this pull requestDec 23, 2024
The no-invalid-void-type issue is beingfixed:typescript-eslint/typescript-eslint#10422
Copy link
Member

@JoshuaKGoldbergJoshuaKGoldberg left a comment
edited
Loading

Choose a reason for hiding this comment

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

Commented inline. Exciting! 🚀

I think just#10422 (comment) is left.

ronami reacted with heart emoji
@JoshuaKGoldbergJoshuaKGoldberg added the awaiting responseIssues waiting for a reply from the OP or another party labelJan 7, 2025
@ronamironami added blocked by another issueIssues which are not ready because another issue needs to be resolved first and removed awaiting responseIssues waiting for a reply from the OP or another party labelsJan 19, 2025
@ronamironami marked this pull request as draftJanuary 19, 2025 18:17
@ronamironami removed the blocked by another issueIssues which are not ready because another issue needs to be resolved first labelJan 29, 2025
@ronami
Copy link
MemberAuthor

Opening for re-review, please note:

  • I've renamed and extractedhasOverloadSignatures to a separate utility because I think it may be useful in other places (e.g.[explicit-module-boundary-types] New option to allow unspecified return type if there are overload signatures #4586).

  • UnlikeFunctionDeclaration, which has a different type of node for its definition (TSDeclareFunction),MethodDefinition doesn't.MethodDefinition seems to either have itsvalue be aFunctionExpression for implementations orTSEmptyBodyFunctionExpression in case of overloading (ignoring type/interface'sTSMethodSignature, which seems like it cannot be part of a class's body).

    hasOverloadSignatures currently requests a node of typeTSESTree.FunctionDeclaration | TSESTree.MethodDefinition, which means that it's possible to pass an overload method definition, for which the function will wrongly returntrue:

    classT{// compiles, even though this is a type errorfoo():string;}

    This doesn't affect theno-invalid-void-type rule, as itonly passes function/method implementations, but it may be an issue for future rules that use this. This can have a stricter type, but it does add a bit of complexity (see350e82f).

    I'm not sure if this is worth the extra complexity, would love to hear another opinion on this 🙃

JoshuaKGoldberg reacted with thumbs up emoji

@ronamironami marked this pull request as ready for reviewFebruary 2, 2025 17:52
Copy link
Member

@JoshuaKGoldbergJoshuaKGoldberg left a comment

Choose a reason for hiding this comment

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

Yeah I think this is great as-is. The utility has no known issues as used right now so we can cross that bridge when we get to it IMO. Awesome stuff! 🙌

ronami and tommie reacted with heart emoji
@JoshuaKGoldbergJoshuaKGoldberg merged commitb688380 intotypescript-eslint:mainFeb 24, 2025
63 checks passed
@ronamironami deleted the no-invalid-void-type-overloading branchFebruary 24, 2025 17:48
@github-actionsgithub-actionsbot locked asresolvedand limited conversation to collaboratorsMar 4, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.
Reviewers

@JoshuaKGoldbergJoshuaKGoldbergJoshuaKGoldberg approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Bug: [no-invalid-void-type] Can't usevoid in return type union for overloaded function
2 participants
@ronami@JoshuaKGoldberg

[8]ページ先頭

©2009-2025 Movatter.jp