-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
[@typescript-eslint/restrict-plus-operands] False positive for type 0|1
8000
#4689
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I am unable to repro this against master. |
I'm also seeing a false positive with this rule that I can't reproduce in a new project. Seems to be related to the upgrade from typescript 4.5 to 4.6 |
This rule hasn't changed in several months, definitely not so in the latest version. So it's doubtful that it was the latest release that broke something. If you can create an isolated repro in either the playground or in a stand-alone git repo, we can definitely help out and take a closer look! Without a repro - we unfortunately can't provide much help. |
This comment was marked as outdated.
This comment was marked as outdated.
Line 6 is the line I added to show the rule is working fine and correctly enabled. It purposely adds a string and a number, which is banned by the rule. Lines 3 and 4 are from your example code. You reported that line 4 errored when it shouldn't. But as shown - I cannot repro. Line 4 does not error. I'll close this for now as cannot repro. |
Updated repro code. Not sure how to reduce more. If you copy it to the playground, it will show the issue. |
Reproduction playground added to issue |
Thanks for following up with more details @viceice! The issue in the playground code snippet is that By the way, as a general tip, instead of posting screenshots of code or CI reports, please post plain text and/or links to playground snippets. Screenshots are harder for us to work with: they can't be copy&pasted and aren't accessible to folks who rely on screenreaders unless they have very detailed alt text / captions. |
Sorry about the pictures, just want to show the issue. I know that adding Will add a git repo for reproduction too. https://github.com/renovate-reproductions/typescript-eslint-issue-4689/blob/0f5918e579a1126fa27e105d6ffab5955a423c2a/index.ts#L10 |
This is a bug with TS. You can repro it in the TS playground - TS intellisense shows that But at the same time TS knows that the type of However in TS v4.5.5 this does not repro - it shows that the type is In TS 4.6.2 the API that we use to get the type ( This is a bug in TS. |
We had ts 4.6.2 with both ts-eslint versions v5.12.1 and v5.13.0 and it started failing on v5.13.0. I see v5.14.0 has added ts v4.6 support. So it's strange to me why it fails on v5.13.0 🤔 |
@bradzacher Can you help me to find or file a typescript bug? I'm not really sure how to do this, as the normal typescript compiler doesn't show any issue. |
Found another sample of failing type inference /* eslint "@typescript-eslint/restrict-template-expressions": ["error"] */
const PREFIX_DOT = 'PREFIX_DOT';
const TYPE_NUMBER = 'TYPE_NUMBER';
const TYPE_QUALIFIER = 'TYPE_QUALIFIER';
export interface BaseToken {
prefix: string;
type: typeof TYPE_NUMBER | typeof TYPE_QUALIFIER;
val: number | string;
isTransition?: boolean;
}
export interface NumberToken extends BaseToken {
type: typeof TYPE_NUMBER;
val: number;
}
export interface QualifierToken extends BaseToken {
type: typeof TYPE_QUALIFIER;
val: string;
}
export type Token = NumberToken | QualifierToken;
// failed version
export function tokensToStr(tokens: Token[]): string {
return tokens.reduce((result, token, idx) => {
const prefix = token.prefix === PREFIX_DOT ? '.' : '-';
return `${result}${idx !== 0 && token.val !== '' ? prefix : ''}${
token.val
}`;
}, '');
}
// fixed version
function tokensToStr1(tokens: Token[]): string {
return tokens.reduce((result:string, token:Token, idx) => {
const prefix = token.prefix === PREFIX_DOT ? '.' : '-';
return `${result}${idx !== 0 && token.val !== '' ? prefix : ''}${
token.val
}`;
}, '');
} repro added to https://github.com/renovate-reproductions/typescript-eslint-issue-4689 |
Okay so in the playground the lib types aren't being loaded - so the array types aren't loaded properly - meaning the ESLint run sees I knew that the Promise types didn't load - but I didn't realise we had this issue for arrays as well. Issue is tracked here #4493 If we manually add the array types it'll work as expected Either way - I just re-tested your cases directly against the master tests (which aren't borked like the playground) and they passed just fine: |
So I simplified your repro further to this eslintrc The interesting thing is that if you remove the lint rule |
I've reduced the repo at https://github.com/renovate-reproductions/typescript-eslint-issue-4689 to be very minimal. @JamieMagee is working to reduce it even futher and will open an upstream issue on typescript. it seems this additional lint rules make a difference config rules: {
// TODO: removing these two lines to remove the lint errors
'@typescript-eslint/no-unsafe-return': 0,
'@typescript-eslint/no-unsafe-argument': 0,
'@typescript-eslint/restrict-template-expressions': [
2,
{ allowNumber: true, allowBoolean: true },
],
'@typescript-eslint/restrict-plus-operands': 2,
}, |
So it seems there is some crossing between those rules, which cause the strange behavior. We do not even have any |
None of our lint rules mutate any of the TS data - they all just read TS data. All TS types are computed lazily - TS computes exactly what you ask for and nothing more! So if I had to hazard a guess, what's happening is that there's a bug in TS wherein it is not computing the correct type information for the variable based solely on the query in I went through and commented out all of the code in Next I commented out code from within its function. When I comment out this line the errors disappear. Screen.Recording.2022-03-17.at.11.04.43.mov |
This will require some effort to create an isolated repro using just the TS APIs in order to submit a proper bug report to TS. |
I have raised microsoft/TypeScript#48313 which covers one of the issues and was easy to isolate just using the playground. |
In case it helps, here are two more examples which trigger this bug. interface Time {
minutes?: number;
}
declare const time: Time;
// Throws @typescript-eslint/restrict-plus-operands
const sum1 = 3 + (time.minutes ?? 0);
if (time.minutes) {
// Throws @typescript-eslint/restrict-plus-operands
const sum2 = 3 + time.minutes;
} |
On the latest TS version, this doesn't seem to be an error anymore. |
Uh oh!
There was an error while loading. Please reload this page.
Repro
happens after update from
v5.12.1
tov5.13.0
.Expected Result
Should not cause an error.
Actual Result

The rule causes a false positive on code above.
https://github.com/renovatebot/renovate/pull/14597/files#diff-f6e993a4715dd7526818c5bb2cdfdaa3a139db2aa290ba8857b9d93f8fe03c4f
Additional Info
Versions
@typescript-eslint/eslint-plugin
5.14.0
@typescript-eslint/parser
5.14.0
TypeScript
4.6.2
ESLint
8.10.0
node
14.19.0
The text was updated successfully, but these errors were encountered: