-
Notifications
You must be signed in to change notification settings - Fork 12.8k
TypeScript Language Server False Positive Error Reporting #57585
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
Minimized repro export interface Result<T, E> {
mapErr<F>(fn: (error: E) => F): Result<T, F>;
[Symbol.iterator](): Generator<E, T>;
}
declare const okIfObject: (value: unknown) => Result<Record<string, unknown>, 'ERR_NOT_AN_OBJECT'>;
declare const okIfInt: (value: unknown) => Result<number, 'ERR_NOT_AN_INT'>;
export declare function Do2<T, E>(job: () => Generator<E, T>): void;
declare let value: unknown;
Do2(function* () {
const object = yield* okIfObject(value).mapErr(
error => 0
);
const age = yield* okIfInt(object.age).mapErr(
error => 0
);
return { age };
}); |
I'm not sure how their rule works. If it depends on type information (looks like it does) then that error should go away after we fix this one. |
Analyzing Ryan's simplified repro the problem comes from Failing test case for this situation: /// <reference path='fourslash.ts'/>
// @strict: true
// @target: esnext
// @lib: esnext
//// export interface Result<T, E> {
//// mapErr<F>(fn: (error: E) => F): Result<T, F>;
//// [Symbol.iterator](): Generator<E, T>;
//// }
////
//// declare const okIfObject: (
//// value: unknown,
//// ) => Result<Record<string, unknown>, "ERR_NOT_AN_OBJECT">;
////
//// declare const okIfInt: (value: unknown) => Result<number, "ERR_NOT_AN_INT">;
////
//// export declare function Do2<T, E>(job: () => Generator<E, T>): void;
////
//// declare let value: unknown;
////
//// Do2(function* () {
//// const object = yield* okIfObject(value).mapErr((error) => 0);
//// const age = yield* okIfInt(object.age).mapErr((error) => 0);
//// return { age };
//// });
verify.encodedSemanticClassificationsLength('2020', 132);
verify.getSemanticDiagnostics([]); |
I spent some time on this to learn what the proper fix could be. I concluded that the only proper fix for this has to be about making the cycle resolution logic smarter - or for the "out of order" type resolution to alter its behavior somehow. No extra flags passed down by the caller can fix this because the compiler doesn't always control the caller. For instance, I managed to somewhat improve the situation locally for the test case above but that didn't fix quick info problem at the very same location: /// <reference path="fourslash.ts" />
// @strict: true
// @target: esnext
// @lib: esnext
//// export interface Result<T, E> {
//// mapErr<F>(fn: (error: E) => F): Result<T, F>;
//// [Symbol.iterator](): Generator<E, T>;
//// }
////
//// declare const okIfObject: (
//// value: unknown,
//// ) => Result<Record<string, unknown>, "ERR_NOT_AN_OBJECT">;
////
//// declare const okIfInt: (value: unknown) => Result<number, "ERR_NOT_AN_INT">;
////
//// export declare function Do2<T, E>(job: () => Generator<E, T>): void;
////
//// declare let value: unknown;
////
//// Do2(function* () {
//// const object/*1*/ = yield* okIfObject(value).mapErr((error) => 0);
//// const age = yield* okIfInt(object.age).mapErr((error) => 0);
//// return { age };
//// });
verify.quickInfoAt("1", "const object: Record<string, unknown>"); One of those calls Perhaps there is a way to fix this by overriding |
Additional repro noted at #57429 (comment) |
@RyanCavanaugh |
Tracking as https://github.com/Effect-TS/effect is also hit by this |
Yep, I was surprised that I found the bug before the Effect team did. |
the reason we didn't find the bug before is that we were using an adapter function so instead of |
#57903 doesn't affect Effect as we don't use async generators (provided I've understood the issue correctly) |
I tried an absolutely terrible idea; in |
Would it be possible to get a snapshot with this idea to test in the effect codebase if it solves all the instances of this issue? |
Sure; watch #58323 for a build once the pipeline completes. |
Interestingly, a modified #57585 (comment) to omit the return like the above is also fixed by my hack, which implies that the error being produced above is a cycle caused by some other query than semantic tokens. tsserver trace logs ( |
the full code to repro this is: import { Effect } from "effect"
Effect.gen(function* () {
const a = yield* Effect.succeed(0)
const b = yield* Effect.succeed(1)
}) the bug presents while you edit, like adding a new line, making changes in general |
Not sure if helpful but you can find the log from tsserver here: https://gist.github.com/mikearnaldi/fc2c4f15135b034d62f0625de82557f4 |
Yeah, that log's really long (the error doesn't happen until message 1020), so would need something shorter. That and you're using a language service plugin, which we generally treat as "voiding all warranties" when it comes to us trying to figure out what's wrong. But I don't think it matters in this case (but do try without it). I can't get that example to reproduce myself, though, only with the return present... |
Much shorter log without the plugin: https://gist.github.com/mikearnaldi/70037e879777f1f3243d0496559c2a99 To reproduce delete the second line: const b = yield* Effect.succeed(1) and re-type it manually, error should appear. I wonder if I can use replay.io to record a session here cc @Andarist |
That log looks truncated; the main reason for the log is to find the steps to get to the bad error, so we need steps from the first message all the way to the error to be able to write an equivalent test which touches everything in the right way. (Hence why a full log and a short one is helpful.) I still wasn't able to make it reproduce when typing it out by hand, though... It's possible my editor did not make the same sequence of calls, of course. |
Try a few times to delete and retype, it's sporadic, doesn't happen always. Will provide a full log tomorrow |
Is there a strong need to provide an extra repro for this if we already have 3 compiler tests written for this here? ;p |
I figured that would be helpful given I fixed the cases that looked |
I working on a fix for this, I'll put something up later this afternoon. |
Does this issue occur when all extensions are disabled?: Yes
Steps to Reproduce:
git clone https://github.com/DScheglov/res-test.git
code res-test
npm i
./src/index.ts
The following errors are shown:

These errors are false positive:
.vscode/settings.json
npx tsc
(no errors)Ctrl + Shift + P
, TypeScript: Restart TS Server)There is not such problem in WebStorm

(Sorry, I have to check)
Errors are not displayed in the TS Playground as well:
Playground
The text was updated successfully, but these errors were encountered: