TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Invalid quick fix for class that's exported as a variable with `isolatedDeclarations`

Open bradzacher opened this issue 6 months ago • 3 comments

🔎 Search Terms

isolatedDeclarations, quick fix, class

🕗 Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play/?isolatedDeclarations=true#code/JYWwDg9gTgLgBAbzgNQgGwK4gKZwL5wBmUEIcA5DiIQM7kDcAUI9gB6SxwDGEAdjfEIQIcALxxe2AO4p0WbAAoAlEyA

💻 Code

import { Volume } from 'memfs';

export const foo = new Volume();

🙁 Actual behavior

The "Add annotation of type Volume" quick fix produces broken code:

import { Volume } from 'memfs';
import { Volume } from 'memfs/lib/volume';

export const foo: Volume = new Volume();

The "Add satisfies and an inline type assertion with Volume" quick fix produces broken code:

import { Volume } from 'memfs';
import { Volume } from 'memfs/lib/volume';

export const foo = (new Volume()) satisfies Volume as Volume;

In both cases the quick fix adds another import which creates a TS error due to the duplicate name. If you remove the added import then there is a different error because Volume in this instance is actually a variable that aliases the class declaration -- so it cannot be used as a type.

🙂 Expected behavior

The quick fix should produce working code.

Additional information about the issue

This might be a unique edge case due to the horrid types in memfs -- IDK why they re-export the class via a variable -- that's seriously cooked.

bradzacher avatar May 02 '25 05:05 bradzacher

Submitted a fix upstream https://github.com/streamich/memfs/pull/1099 but regardless the TS quick fix should behave correctly here.

bradzacher avatar May 02 '25 05:05 bradzacher

The quick fix should produce working code.

What's the correct code in this case?

RyanCavanaugh avatar May 02 '25 17:05 RyanCavanaugh

What's the correct code in this case?

I'd say one of these two:

import { Volume } from 'memfs';

export const foo: InstanceType<typeof Volume> = new Volume();

or:

import { Volume } from 'memfs';
import { Volume as $SomeUniqueMarker$Volume } from 'memfs/lib/volume';

export const foo: $SomeUniqueMarker$Volume = new Volume();

bradzacher avatar May 05 '25 03:05 bradzacher